0

簡単な質問:event.preventDefault()要素が「キャプチャ」、「アット」、および「バブリング」フェーズの一部である限り、イベント ハンドラーを設定した要素に関係なく実行できますか?

ページ上ですべてを選択できないようにしたかったので、最初はやりたかった

document.addEventListener("selectstart", function(ev) {
  ev.stopPropagation();
}, true);

キャプチャ フェーズの最初の段階では、ページ コンテンツ要素に伝播しないため、選択は行われません。

ただし、伝播が停止しても、デフォルトのアクションは引き続き実行されるようです。

そして、キャプチャフェーズでこれを実行しようとしました:

document.addEventListener("selectstart", function(ev) {
  ev.preventDefault();
}, true);

次に、をに変更しtruefalse、バブリング フェーズ中にハンドラーが呼び出されるようにします。

document.addEventListener("selectstart", function(ev) {
  ev.preventDefault();
}, false);

それも機能します。

「preventDefault」は要素ごとだと思っていました。

したがって、キャプチャ段階、段階、バブリング段階のすべてで呼び出すことができev.preventDefault()、それはまったく同じイベントオブジェクトであり、ハンドラーを設定する要素に関係なく、デフォルトのアクションを防ぐことができます。要素は「キャプチャ」、「アット」、および「バブリング」ループにありますか?

4

1 に答える 1

1

文字通り同じイベント オブジェクトであるか、実装が同じように動作します。私は、これらのどれがブラウザ間で当てはまるかを自分自身に証明したことはありません. :-) 文字通り同じオブジェクトであることはほぼ確実です。(下記参照。)

しかし、はい、イベントを呼び出すpreventDefaultと、いつ実行するかに関係なく、ブラウザーにデフォルトのアクションを実行しないように指示されます。


それが同じオブジェクトであることを証明しましょう:

var CAPTURE = true;
var BUBBLING = false
var current = null;
hook(document.body, "body");
hook(document.getElementById("middle"), "middle");
hook(document.getElementById("target"), "target");

function hook(element, name) {
  element.addEventListener("click", function(e) {
    if (element === document.body) {
      console.log(name + " capture");
      current = e;
    } else {
      console.log(name + " capture, same? " + (e === current));
    }
  }, CAPTURE);
  var phase = name === "target" ? "target" : "bubbling";
  element.addEventListener("click", function(e) {
    console.log(name + " " + phase + ", same? " + (current === e));
  }, BUBBLING);
}
<div id="middle">
  <div id="target">Click me</div>
</div>

そのコードを IE9、IE11、Chrome、Firefox で試してみました。それはそれらすべての同じオブジェクトでした。Scott Marcusは、Edge も同じことをしていると語っています。

于 2017-04-28T16:09:31.487 に答える