ドキュメントには2つのスクリプトがあります
// my_script.js goes first
document.onclick = function() {
alert("document clicked");
};
// other_script.js comes after
// this overrides the onclick of my script,
// and alert will NOT be fired
document.onclick = function() {
return false;
};
クリックイベントが他のスクリプトによって上書きされないようにするために、addEventListener
に切り替えました。
// my_script.js goes first
document.addEventListener("click", function() {
alert("document clicked");
}, false);
// other_script.js comes after
document.addEventListener("click", function() {
return false;
}, false);
今、私は別の質問を受けました。 2番目のコードのreturn false
はalert
の後に定義されているのに、なぜアラートの呼び出しを妨げないのでしょうか。
スクリプトでクリックイベントを完全に制御したい場合はどうなりますか(他のスクリプトで定義されているイベントを無視して常にfalseを返すなど)?
スクリプトでクリックイベントを完全に制御したい場合はどうなりますか(他のスクリプトで定義されているイベントを無視して常にfalseを返すなど)?
ハンドラーを最初に登録できる場合は、登録する前に、使用しているブラウザーがDOM3イベントを正しく実装していれば(IE8以前でない限り、おそらく登録します)、登録できます。
ここには(少なくとも)4つのことが関係しています:
デフォルトを防ぐ。
祖先要素への伝播を停止します。
same要素の他のハンドラーが呼び出されないようにします。
ハンドラーが呼び出される順序。
順番に:
これは、DOM0ハンドラーのreturn false
が行うことです。 (詳細: False を返すストーリー。)DOM2とDOM3で同等のものは preventDefault
:
document.addEventListener("click", function(e) {
e.preventDefault();
}, false);
デフォルトを防ぐことは、あなたがしていることにそれほど関係がないかもしれませんが、DOM0ハンドラーでreturn false
を使用していて、それがデフォルトを防ぐので、完全を期すためにここに含めます。
DOM0ハンドラーにはこれを行う方法がありません。 DOM2のものは、 stopPropagation
を介して行います:
document.addEventListener("click", function(e) {
e.stopPropagation();
}, false);
ただし、stopPropagation
は、同じ要素の他のハンドラーが呼び出されるのを停止しません。から 仕様 :
stopPropagation
メソッドが使用され、イベントフロー中にイベントがさらに伝播するのを防ぎます。このメソッドがEventListener
によって呼び出された場合、イベントはツリー内での伝播を停止します。 イベントは、イベントフローが停止する前に、現在のEventTarget
上のすべてのリスナーへのディスパッチを完了します。
(私の強調。)
当然、これはDOM0では発生しませんでした。これは、同じ要素で同じイベントに対して他のハンドラーがbeできないためです。 :-)
私の知る限り、DOM2でこれを行う方法はありませんが、DOM3では stopImmediatePropagation
:
document.addEventListener("click", function(e) {
e.stopImmediatePropagation();
}, false);
一部のライブラリは、ライブラリを介して接続されたハンドラーに対してこの機能を提供します(IE8などの非DOM3システムでも)。以下を参照してください。
繰り返しますが、他のハンドラーは存在し得ないため、DOM0に関連するものではありません。
DOM2では、仕様explicitlyは、要素にアタッチされたハンドラーが呼び出される順序が保証されていないことを示しています。しかし、DOM3はそれを変更し、ハンドラーは登録された順序で呼び出されると言っています。
まず、DOM2から セクション1.2.1 :
EventListeners
上のすべてのEventTarget
は、そのEventTarget
によって受信されたイベントによってトリガーされることが保証されていますが、受信する順序については指定されていません。EventListeners
上の他のEventTarget
に関するイベント。
しかし、これはDOM3に取って代わられます セクション3.1 :
次に、実装は現在のターゲットの候補イベントリスナーを決定する必要があります。これは、現在のターゲットに登録されているすべてのイベントリスナーのリストである必要があります。
(私の強調。)
一部のライブラリは、イベントをライブラリに接続することを条件に、順序を保証します。
また、MicrosoftのDOM2の前身(例:attachEvent
)では、DOM3の順序とは逆でした。ハンドラーは逆の登録順序で呼び出されていました。 。
したがって、#3と#4を一緒にすると、ハンドラーを最初に登録できる場合は、ハンドラーが最初に呼び出され、stopImmediatePropagation
を使用して他のハンドラーが呼び出されないようにすることができます。ブラウザがDOM3を正しく実装している場合。
これらすべて(IE8以前はDOM2イベントを実装しておらず、DOM3も実装していないという事実を含む)は、jQueryのようなライブラリを使用する理由の1つであり、その一部は順序を保証します(すべてがを介してハンドラーを接続している限り)問題のライブラリ)、同じ要素上の他のハンドラーでさえも呼び出されないようにする方法を提供します。 (たとえば、jQueryの場合、順序はアタッチされた順序であり、stopImmediatePropagation
を使用して他のハンドラーへの呼び出しを停止できます。ただし、ここではjQueryを販売しようとはしておらず、 libsは、基本的なDOMのものよりも多くの機能を提供します。)