インラインのonclick属性でイベントの伝播を停止する方法は?


313

以下を検討してください。

<div onclick="alert('you clicked the header')" class="header">
  <span onclick="alert('you clicked inside the header');">something inside the header</span>
</div>

ユーザーがスパンをクリックしたときにdivのクリックイベントが発生しないようにするにはどうすればよいですか?

回答:


272

event.stopPropagation()を使用します。

<span onclick="event.stopPropagation(); alert('you clicked inside the header');">something inside the header</span>

IEの場合: window.event.cancelBubble = true

<span onclick="window.event.cancelBubble = true; alert('you clicked inside the header');">something inside the header</span>

11
FireFoxには、イベントオブジェクトなどはありません。
ロバートC.バース

6
イベントオブジェクトは、コールバックのパラメーターです。実際には、このオブジェクトは関数のパラメーターではなくwindow.eventからアクセスできるため、IEにはイベントオブジェクトなどはありません:-)
Vincent Robert

66
これは間違っています。インラインのonclickハンドラは、イベントを引数として渡されません。正しい解決策は、以下のGarethsです。
Benubird

2
Firefoxでは、インラインスクリプトで変数イベントにアクセスできますが、window.eventは使用できません。<div onclick = "alert(event);"> </ div>
Morgan Cheng、

1
eventIOS Safariのインラインイベントでも利用できるようです。
Yuval A.

210

関数内からイベントオブジェクトを取得する方法は2つあります。

  1. W3C準拠ブラウザー(Chrome、Firefox、Safari、IE9 +)の最初の引数
  2. Internet Explorerのwindow.eventオブジェクト(<= 8)

W3Cの推奨事項に準拠していないレガシーブラウザをサポートする必要がある場合は、通常、関数内で次のようなものを使用します。

function(e) {
  var event = e || window.event;
  [...];
}

最初にチェックし、次にもう1つをチェックして、イベント変数内で見つかったものを保存します。ただし、インラインイベントハンドラーでは、e使用するオブジェクトはありません。その場合、arguments常に利用可能で、関数に渡される引数の完全なセットを参照するコレクションを利用する必要があります。

onclick="var event = arguments[0] || window.event; [...]"

ただし、一般的に言えば、伝播の停止などの複雑な処理が必要な場合は、インラインイベントハンドラーを回避する必要があります。イベントハンドラーを個別に記述して要素にアタッチすることは、中長期的には、読みやすさと保守性の両方の点ではるかに優れたアイデアです。


11
インラインリスナーから、次のようにイベントオブジェクトを渡すことができonclick="foo(event)"ますfunction foo(event){/* do stuff with event */}。これは、IEとW3Cの両方のイベントモデルで機能します。
RobG 2014

5
その「8以下」はややあいまいです。
TechNyquist 16

8
これは実際には質問の答えにはなりません。
jcomeau_ictx 2017年

1
別の質問へのきちんとした答え。:-/
Arel

80

window.eventはFireFoxではサポートされていないため、次のようにする必要があることに注意してください。

e.cancelBubble = true

または、FireFoxのW3C標準を使用できます。

e.stopPropagation();

ファンシーになりたい場合は、これを行うことができます:

function myEventHandler(e)
{
    if (!e)
      e = window.event;

    //IE9 & Other Browsers
    if (e.stopPropagation) {
      e.stopPropagation();
    }
    //IE8 and Lower
    else {
      e.cancelBubble = true;
    }
}

12
そして、それを機能させるために、1ニーズは次のようにこれを呼び出すには:<div onclick="myEventHandler(event);">
DarkDust

1
「イベント|| window.event」のようになります。
とがった

1
(e.cancelBubble)が私に正しく見えない場合、すでにtrueになっている場合はtrueに設定します
Guillaume86

e.cancelBubbleIEでfalseを返します!e.cancelBubble = true;指示に到達できません。代わりにSoftwareARMの条件を使用してください!!
mauretto 2012年

45

この関数を使用すると、正しいメソッドが存在するかどうかがテストされます。

function disabledEventPropagation(event)
{
   if (event.stopPropagation){
       event.stopPropagation();
   }
   else if(window.event){
      window.event.cancelBubble=true;
   }
}

20

私は同じ問題を抱えていました-IEのjsエラーボックス-これは私が見る限りすべてのブラウザーで正常に機能します(event.cancelBubble = trueはIEで機能します)

onClick="if(event.stopPropagation){event.stopPropagation();}event.cancelBubble=true;"

1
@MSCに感謝します。
DannyC 2015

1
インラインスクリプト。それは質問に答えます
Cesar

10

これは私のために働いた

<script>
function cancelBubble(e) {
 var evt = e ? e:window.event;
 if (evt.stopPropagation)    evt.stopPropagation();
 if (evt.cancelBubble!=null) evt.cancelBubble = true;
}
</script>

<div onclick="alert('Click!')">
  <div onclick="cancelBubble(event)">Something inside the other div</div>
</div>

この正確なコードスニペットが機能したことを確信していますか?外側のdivのonclickハンドラーに文字列の引用の問題があるように見えるので...?!
ニコール

7

ASP.NET Webページ(MVCではない)では、Sys.UI.DomEventオブジェクトをネイティブイベントのラッパーとして使用できます。

<div onclick="event.stopPropagation();" ...

または、イベントをパラメーターとして内部関数に渡します。

<div onclick="someFunction(event);" ...

そしてsomeFunctionで:

function someFunction(event){
    event.stopPropagation(); // here Sys.UI.DomEvent.stopPropagation() method is used
    // other onclick logic
}


2

Karmaのせいでコメントできないので、全体の答えとしてこれを記述します。高速ハック:

<div onclick="(arguments[0] || window.event).stopPropagation();">..</div>

遅いのはわかっていますが、これが1行で機能することをお知らせします。中括弧は、どちらの場合もstopPropagation-functionが付加されたイベントを返すため、ifおよび...のように中括弧でそれらをカプセル化しようとしました。:)


1

これも機能します-リンクHTMLでは、onclickとreturnを次のように使用します。

<a href="mypage.html" onclick="return confirmClick();">Delete</a>

そして、comfirmClick()関数は次のようになります。

function confirmClick() {
    if(confirm("Do you really want to delete this task?")) {
        return true;
    } else {
        return false;
    }
};

2
これは質問の意味ではありません。
jzonthemtn 2013

@jbirdそれがまさに質問が意味したことです。これは、イベントをdomツリーを泡立たせることからキャンセルする別の(古い)方法です(dom apiレベル1仕様にあります)。
gion_13 2013年

@ gion_13しかし、クリックのアクションは、ユーザーが確認する必要があるものではありません。質問では、子のonclick()のみを起動し、親のonclick()は起動しないようにします。それらの間にユーザープロンプトを置くことは役に立ちません。この違いをご覧いただければ幸いです。
jzonthemtn 2013年

1
confirm関係ありません。戻り値を参考にしています。quote:リンクHTMLでは、onclick を次のように
gion_13

リンクをたどるとfalseキャンセルが返され、
Chromeでの

1

クリックされた要素を確認しないでください。あなたが何かをクリックすると、window.event.targetクリックされた要素に割り当てられている、クリックされた要素は、引数として渡すことができます。

ターゲットと要素が等しくない場合、それは上に伝播したイベントでした。

function myfunc(el){
  if (window.event.target === el){
      // perform action
  }
}
<div onclick="myfunc(this)" />

おかげで、これはここで最もきれいな解決策のようです。ただし、注意する必要があるのは、クリックされた要素が実際の最上位の要素である場合にのみ一致することです。
Simon Mattes

0
<div onclick="alert('you clicked the header')" class="header">
  <span onclick="alert('you clicked inside the header'); event.stopPropagation()">
    something inside the header
  </span>
</div>

0

最善の解決策は、JavaScript関数を介してイベントを処理することですが、html要素を直接使用するシンプルで迅速な解決策を使用するため、「event」と「window.event」は廃止され、普遍的にサポートされていません(https://developer.mozilla.org/en-US/docs/Web/API/Window/event)、私は次の「ハードコード」を提案します:

<div onclick="alert('blablabla'); (arguments[0] ? arguments[0].stopPropagation() : false);">...</div>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.