web-dev-qa-db-ja.com

子アンカーがクリックされたときに親のonclickイベントが発生しないようにする方法を教えてください。

私は現在divをクリック可能にするためにjQueryを使用しています。このdivにはアンカーもあります。私が遭遇した問題は、私がアンカーをクリックしたときに両方のクリックイベントが発生するということです(divとアンカーのために)。アンカーがクリックされたときにdivのonclickイベントが発生しないようにするにはどうすればよいですか?

これが壊れたコードです。

JavaScript

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>
295
Jonathon Watney

イベントは、クリックイベントが添付されたDOMの最も高い位置にバブルします。そのため、divに明示的にクリック可能な要素が他になくても、divのすべての子要素は、DIVのclickイベントハンドラがそれをキャッチするまで、DOMの上でクリックイベントをバブルします。

これに対する2つの解決策は、実際に誰がイベントを起こしたのかを確認することです。 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();
});
397
Rex M

stopPropagation メソッドを使用します。例を参照してください。

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

JQuery Docsが言ったように:

stopPropagationname__メソッドは、イベントがDOMツリーを膨らませるのを防ぎ、親ハンドラーにイベントが通知されるのを防ぎます。

他のリスナーがこのイベントを処理するのを妨げることはありません(例:ボタンに対して複数のクリックハンドラ)、それが望ましい効果でない場合は、代わりにstopImmediatePropagationname__を使用する必要があります。

91
Cleiton

非jQueryコード(純粋なjavascript)を探しているすべての人のためのここに私のソリューション

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

親の子供をクリックした場合、あなたのコードは実行されません

41
Sabaz

あなたもこれを試すことができます

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

いずれにせよ内部要素とやり取りするつもりがないのであれば、CSSソリューションが役に立ちます。

内側の要素をpointer-events: noneに設定するだけです。

あなたの場合:

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

または一般的にすべての内部要素をターゲットにします。

.clickable * {
    pointer-events: none;
}

ReactJSで開発している間、この簡単なハックは私に多くの時間を節約しました

ブラウザサポートはここで見つけることができました: http://caniuse.com/#feat=pointer-events

11
Hooman Askari

return false;またはe.stopPropogation();を使用しても、それ以上コードを実行することはできません。それはこの時点でそれ自体で流れを止めます。

8
Imamudin Naseem

クリッカブルdivに複数の要素がある場合は、これを実行する必要があります。

$('#clickable *').click(function(e){ e.stopPropagation(); });
7
Ivan Ivković

誰かが必要な場合に書く(私のために働いた):

event.stopImmediatePropagation()

この の解から。

5

これは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();
}
3
Steve Brush

イベントが親(div)に到達(バブリング)しないようにする必要があります。バブリングに関する部分 はこちら 、jQuery固有のAPI情報 はこちら

1
Matt Ball
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>
1
Pramod Kharade

ignoreParent()は純粋なJavaScriptソリューションです。

これは、マウスクリックの座標と子要素の座標を比較する中間層として機能します。 2つの簡単な実装手順

1。ignoreParent()コードをページに配置します。

2。親のオリジナルのonclick = "parentEvent();"の代わりに、

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

任意の数の子要素のIDを関数に渡して、他の要素を除外することができます。

子要素の1つをクリックした場合、親イベントは発生しません。 parentをクリックしたが、(引数として提供された)どの子要素もクリックしなかった場合、parentイベントが発生します。

Githubの ignoreParent()コード

0
Fom

インライン代替:

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

誰かが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でモーダル効果を作成することができました。

0
Claudio

クリックできないようにいくつかのサブ要素を指定するには、以下の例のようにCSS階層を書きます。

この例では、クラス "。subtable"を持つテーブルの中のtrの中のtdの中の任意の要素(*)への伝播を停止します。

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

});
0
user3202819