자식 앵커를 클릭 할 때 부모의 onclick 이벤트가 발생하지 않도록하려면 어떻게해야합니까?


348

현재 jQuery를 사용하여 div를 클릭 가능하게 만들고이 div에는 앵커도 있습니다. 내가 겪고있는 문제는 앵커를 클릭 할 때 두 클릭 이벤트가 모두 발생한다는 것입니다 (div 및 앵커). 앵커를 클릭 할 때 div의 onclick 이벤트가 발생하지 않도록하려면 어떻게합니까?

깨진 코드는 다음과 같습니다.

자바 스크립트

var url = $("#clickable a").attr("href");

$("#clickable").click(function() {
    window.location = url;
    return true;
})

HTML

<div id="clickable">
    <!-- Other content. -->
    <a href="http://foo.com">I don't want #clickable to handle this click event.</a>
</div>

답변:


460

클릭 이벤트가 연결된 DOM에서 이벤트가 버블 링됩니다. 따라서 귀하의 예에서 div에 명시 적으로 클릭 가능한 다른 요소가 없더라도 div의 모든 자식 요소는 DIV의 click 이벤트 핸들러가 그것을 잡을 때까지 click 이벤트를 DOM으로 버블 링합니다.

누가 실제로 이벤트를 시작했는지 확인하는 방법이 두 가지 있습니다. jQuery는 이벤트와 함께 eventargs 객체를 전달합니다.

$("#clickable").click(function(e) {
    var senderElement = e.target;
    // Check if sender is the <div> element e.g.
    // if($(e.target).is("div")) {
    window.location = url;
    return true;
});

클릭 이벤트 핸들러를 링크에 연결 하여 자체 핸들러가 실행 된 후 이벤트 버블 링중지 하도록 지시 할 수 있습니다 .

$("#clickable a").click(function(e) {
   // Do something
   e.stopPropagation();
});

3
좋은 대답입니다. 옵션도 있다는 것을 알고 반갑습니다.
Jonathon Watney

4
+1! stopPropagation으로 클릭 핸들러를 연결하는 것은 매우 좋은 방법입니다. 감사합니다!
Thomas

2
전파를 막고 자하는 요소가 많으면 부모 요소를 찾아서 머리 위로 거품이 생기는 것을 방지 할 수 있습니다. 예를 들어 div의 모든 링크를 가로 채지 않고 div 자체의 클릭조차 가로 채서 더 이상 올라가지 않도록 설정하십시오.
sucitivel

21
다른 사람이 자식에 일부 처리기를 연결하는지 또는 라이브러리가 자식에 처리기를 연결해야 하는지를 알지 못하기 때문에 if( e.target !== this) return;부모에서 사용 하는 것이 e.stopPropagation()자식 보다 낫습니다 . 더 나은 관심사 분리입니다.
UTF_or_Death

3
퍼팅 if( e.target !== this) return;자신의 핸들러를 온 클릭하지 않아도 부모의 다른 아이들 중 하나를 클릭 할 경우, 다음 아무 변화가 없다는 것을 부모 수단에 확인. 따라서 클릭 가능한 부모 div가있는 상황에서는 쓸모가 없습니다. e.stopPropagation()그러나 잘 작동합니다.
derf26

101

stopPropagation 메소드를 사용 하십시오 (예 참조).

$("#clickable a").click(function(e) {
   e.stopPropagation();
});

jQuery Docs가 말했듯이 :

stopPropagation 메소드는 이벤트가 DOM 트리를 버블 링하는 것을 방지하여 상위 핸들러가 이벤트를 통지하지 못하게합니다.

다른 청취자가이 이벤트를 처리하는 것을 막을 수는 없다는 것을 명심하십시오 (예를 들어, 버튼에 대해 하나 이상의 클릭 핸들러), 원하는 효과가 아닌 경우 stopImmediatePropagation대신 사용해야 합니다.


48

여기에 비 jQuery 코드를 찾는 모든 사람들을위한 내 솔루션 (순수한 자바 스크립트)

document.getElementById("clickable").addEventListener("click", function( e ){
    e = window.event || e; 
    if(this === e.target) {
        // put your code here
    }
});

부모의 자녀를 클릭하면 코드가 실행되지 않습니다


1
이것은 저에게 효과적이었습니다 .JS가 아닌 jQuery 솔루션이 필요했습니다. 10 배!
LA

좋은 대답입니다. 방금 이벤트를 직접 통과했습니다. 그래서 나는 window.eventMDN을 권장 하지 않는 developer.mozilla.org/en-US/docs/Web/API/Window/event를 사용하지 않았다 . 시간을 절약 할 수 있다면 왜 사용했는지 설명 할 수 있다면 감사하겠습니다 window.event(2015 년에 존재했던 문제이거나 이유를 이해하지 못했습니다).
RMo

15

당신은 또한 이것을 시도 할 수 있습니다

$("#clickable").click(function(event) {
   var senderElementName = event.target.tagName.toLowerCase();
   if(senderElementName === 'div')
   {
       // do something here 
   } 
   else
   {
      //do something with <a> tag
   }
});

14

어떤 경우에도 내부 요소와 상호 작용하지 않으려는 경우 CSS 솔루션이 유용 할 수 있습니다.

내부 요소를로 설정하십시오. pointer-events: none

귀하의 경우 :

.clickable > a {
    pointer-events: none;
}

또는 모든 내부 요소를 일반적으로 타겟팅하기 위해 :

.clickable * {
    pointer-events: none;
}

이 쉬운 해킹은 ReactJS로 개발하는 동안 많은 시간을 절약했습니다.

브라우저 지원은 여기에서 찾을 수 있습니다 : http://caniuse.com/#feat=pointer-events


8

클릭 가능한 div에 여러 요소가있는 경우 다음을 수행하십시오.

$('#clickable *').click(function(e){ e.stopPropagation(); });

8

사용 return false;하거나 e.stopPropogation();추가 코드를 실행할 수 없습니다. 이 시점에서 흐름이 중지됩니다.


예, 이것이 중요합니다. 그러나 Rex의 위의 대답은 도움이됩니다-클릭 된 요소를 얻을 수 있으며 경우에 따라 중지하려는 논리에 이것을 사용할 수 있습니다. .target.nodeName은 또한 무엇을 공격했는지 명확하게 파악하는 데 도움이되었습니다.
Watercayman


4

인라인 대안 :

<div>
    <!-- Other content. -->
    <a onclick='event.stopPropagation();' href="http://foo.com">I don't want #clickable to handle this click event.</a>
</div>

3

다음은 Angular 2 이상을 사용하는 예입니다

예를 들어, 사용자가 외부를 클릭하면 모달 구성 요소를 닫으려는 경우 :

// Close the modal if the document is clicked.

@HostListener('document:click', ['$event'])
public onDocumentClick(event: MouseEvent): void {
  this.closeModal();
}

// Don't close the modal if the modal itself is clicked.

@HostListener('click', ['$event'])
public onClick(event: MouseEvent): void {
  event.stopPropagation();
}

1

이벤트가 상위 (div)에 도달 (버블 링)하는 것을 중지해야합니다. 버블 링에 대한 부분 및 여기 에서 jQuery 관련 API 정보를 참조하십시오 .


멋있는. 이벤트 버블 링에 대한 정보를 주셔서 감사합니다.
Jonathon Watney

1

var inner = document.querySelector("#inner");
var outer = document.querySelector("#outer");
inner.addEventListener('click',innerFunction);
outer.addEventListener('click',outerFunction);

function innerFunction(event){
  event.stopPropagation();
  console.log("Inner Functiuon");
}

function outerFunction(event){
  console.log("Outer Functiuon");
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Pramod Kharade-Event with Outer and Inner Progration</title>
</head>
<body>
<div id="outer" style="width:100px;height:100px;background-color:green;">
  <div id="inner" style="width:35px;height:35px;background-color:yellow;"></div>
</div>
</body>
</html>


0

클릭 할 수없는 일부 하위 요소를 지정하려면 아래 예와 같이 CSS 계층을 작성하십시오.

이 예제에서는 클래스 ".subtable"을 사용하여 테이블 내부의 tr 내부 td 내부의 모든 요소 (*)에 대한 전파를 중지합니다.

$(document).ready(function()
{    
   $(".subtable tr td *").click(function (event)
   {
       event.stopPropagation();
   });

});

0

ignoreParent () 는 순수한 JavaScript 솔루션입니다.

마우스 클릭의 좌표와 자식 요소의 좌표를 비교하는 중개 레이어로 작동합니다. 두 가지 간단한 구현 단계 :

1. 페이지에 ignoreParent () 코드를 입력하십시오.

2. 부모의 원본 대신 onclick = "parentEvent ();" 쓰기 :

onclick="ignoreParent(['parentEvent()', 'child-ID']);"

여러 하위 요소의 ID를 함수에 전달하고 다른 하위 요소를 제외 할 수 있습니다.

하위 요소 중 하나를 클릭하면 상위 이벤트가 발생하지 않습니다. 인수로 제공된 하위 요소가 아닌 상위를 클릭하면 상위 이벤트가 시작됩니다.

Github의 ignoreParent () 코드


0

인라인 컨텍스트에 있으면 HTML에서 다음을 시도하십시오.

onclick="functionCall();event.stopPropagation();

-1

누군가 React를 사용 하여이 문제가 발생하면이를 해결하는 방법입니다.

scss :

#loginBackdrop {
position: absolute;
width: 100% !important;
height: 100% !important;
top:0px;
left:0px;
z-index: 9; }

#loginFrame {
width: $iFrameWidth;
height: $iFrameHeight;
background-color: $mainColor;
position: fixed;
z-index: 10;
top: 50%;
left: 50%;
margin-top: calc(-1 * #{$iFrameHeight} / 2);
margin-left: calc(-1 * #{$iFrameWidth} / 2);
border: solid 1px grey;
border-radius: 20px;
box-shadow: 0px 0px 90px #545454; }

컴포넌트의 render () :

render() {
    ...
    return (
        <div id='loginBackdrop' onClick={this.props.closeLogin}>
            <div id='loginFrame' onClick={(e)=>{e.preventDefault();e.stopPropagation()}}>
             ... [modal content] ...
            </div>
        </div>
    )
}

자식 모달 (content div)에 대한 onClick 함수를 추가하면 마우스 클릭 이벤트가 부모 요소의 'closeLogin'함수에 도달 할 수 없습니다.

이것은 나를 위해 속임수를 쓰고 2 개의 간단한 div로 모달 효과를 만들 수있었습니다.


-3

a다음과 같이 추가하십시오 .

<a href="http://foo.com" onclick="return false;">....</a>

또는 return false;클릭 핸들러에서 다음 #clickable과 같이하십시오.

  $("#clickable").click(function() {
        var url = $("#clickable a").attr("href");
        window.location = url;
        return false;
   });

-3

모든 솔루션은 복잡하고 jscript입니다. 가장 간단한 버전은 다음과 같습니다.

var IsChildWindow=false;

function ParentClick()
{
    if(IsChildWindow==true)
    {
        IsChildWindow==false;
        return;
    }
    //do ur work here   
}


function ChildClick()
{
    IsChildWindow=true;
    //Do ur work here    
}

3
"IsChildWindow == false;"줄에서 실수 한 것 같습니다. - "IsChildWindow = false;"가 아니어야합니까?
Andre Schweighofer 2012 년

-5
<a onclick="return false;" href="http://foo.com">I want to ignore my parent's onclick event.</a>

5
또한 링크가 탐색되지 않습니다.
Rex M

예, 아니면 무엇이 필요하지 않습니까? 아니면 네브가 필요하십니까?
andres descalzo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.