私は現在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>
イベントは、クリックイベントが添付された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();
});
stopPropagation メソッドを使用します。例を参照してください。
$("#clickable a").click(function(e) {
e.stopPropagation();
});
JQuery Docsが言ったように:
stopPropagation
name__メソッドは、イベントがDOMツリーを膨らませるのを防ぎ、親ハンドラーにイベントが通知されるのを防ぎます。
他のリスナーがこのイベントを処理するのを妨げることはありません(例:ボタンに対して複数のクリックハンドラ)、それが望ましい効果でない場合は、代わりにstopImmediatePropagation
name__を使用する必要があります。
非jQueryコード(純粋なjavascript)を探しているすべての人のためのここに私のソリューション
document.getElementById("clickable").addEventListener("click", function( e ){
e = window.event || e;
if(this === e.target) {
// put your code here
}
});
親の子供をクリックした場合、あなたのコードは実行されません
あなたもこれを試すことができます
$("#clickable").click(function(event) {
var senderElementName = event.target.tagName.toLowerCase();
if(senderElementName === 'div')
{
// do something here
}
else
{
//do something with <a> tag
}
});
いずれにせよ内部要素とやり取りするつもりがないのであれば、CSSソリューションが役に立ちます。
内側の要素をpointer-events: none
に設定するだけです。
あなたの場合:
.clickable > a {
pointer-events: none;
}
または一般的にすべての内部要素をターゲットにします。
.clickable * {
pointer-events: none;
}
ReactJSで開発している間、この簡単なハックは私に多くの時間を節約しました
ブラウザサポートはここで見つけることができました: http://caniuse.com/#feat=pointer-events
return false;
またはe.stopPropogation();
を使用しても、それ以上コードを実行することはできません。それはこの時点でそれ自体で流れを止めます。
クリッカブルdivに複数の要素がある場合は、これを実行する必要があります。
$('#clickable *').click(function(e){ e.stopPropagation(); });
これは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();
}
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>
ignoreParent()は純粋なJavaScriptソリューションです。
これは、マウスクリックの座標と子要素の座標を比較する中間層として機能します。 2つの簡単な実装手順
1。ignoreParent()コードをページに配置します。
2。親のオリジナルのonclick = "parentEvent();"の代わりに、
onclick="ignoreParent(['parentEvent()', 'child-ID']);"
任意の数の子要素のIDを関数に渡して、他の要素を除外することができます。
子要素の1つをクリックした場合、親イベントは発生しません。 parentをクリックしたが、(引数として提供された)どの子要素もクリックしなかった場合、parentイベントが発生します。
Githubの ignoreParent()コード
インライン代替:
<div>
<!-- Other content. -->
<a onclick='event.stopPropagation();' href="http://foo.com">I don't want #clickable to handle this click event.</a>
</div>
誰かが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でモーダル効果を作成することができました。
クリックできないようにいくつかのサブ要素を指定するには、以下の例のようにCSS階層を書きます。
この例では、クラス "。subtable"を持つテーブルの中のtrの中のtdの中の任意の要素(*)への伝播を停止します。
$(document).ready(function()
{
$(".subtable tr td *").click(function (event)
{
event.stopPropagation();
});
});