event.preventDefault()
とreturn false
が同じかどうか疑問に思いました。
一部のテスト を実行しましたが、
たとえば、イベントハンドラーが古いモデルを使用して追加された場合
elem.onclick = function(){
return false;
};
次に、return false
は、event.preventDefault()
などのデフォルトのアクションを防止します。
たとえば、addEventListener
を使用してイベントハンドラーを追加する場合
elem.addEventListener(
'click',
function(e){
return false;
},
false
);
次に、return false
はデフォルトのアクションを妨げません。
すべてのブラウザはこのように動作しますか?
event.preventDefault()
とreturn false
にはさらに違いがありますか?
場合によってはreturn false
がevent.preventDefault()
のように振る舞うことに関するいくつかのドキュメントを見つけることができます(MDNではできませんでした)。
私の質問は、jQueryではなくプレーンなJavaScriptのみに関するものなので、両方の質問のタイトルがほぼ同じであっても、 event.preventDefault()vs. return false の重複としてマークしないでください。
W3Cドキュメントオブジェクトモデルイベント仕様 in1.3.1。イベント登録インターフェイスは、EventListenerのhandleEvent
に戻り値がないことを示しています。
handleEvent
このメソッドは、EventListenerインターフェイスが登録されたタイプのイベントが発生するたびに呼び出されます。 [...]戻り値なし
1.2.4。イベントのキャンセルドキュメントには、
キャンセルは、イベントのpreventDefaultメソッドを呼び出すことで実行されます。イベントフローのいずれかの段階で1つ以上のEventListenersがpreventDefaultを呼び出すと、デフォルトアクションがキャンセルされます。
どのブラウザでもtrue/falseを返し、event.preventDefault()
を使用する可能性のある効果を使用しないようにする必要があります。
更新
HTML5仕様は、実際には、異なる戻り値の処理方法を指定しています。 HTML仕様のセクション7.1.5.1 は
戻り値がWebIDLブールfalse値の場合、イベントをキャンセルします。
「マウスオーバー」イベント以外のすべてのために。
結論
古い仕様、つまり古いブラウザと互換性があるため、ほとんどのプロジェクトでevent.preventDefault()
を使用することをお勧めします。 Edgeブラウザの切断のみをサポートする必要がある場合にのみ、falseを返してキャンセルします。
以下は、人々が問題をよりよく理解し、トラブルシューティングするのに役立つかもしれないいくつかの例です。
onclick
をHTMLマークアップで直接使用する場合、またはsetAttribute('onclick'...)
を介して使用する場合、onclick=
の内容がonclick
関数にラップされるため、実際に戻ることを確認するという点で落とし穴があります。onclick
を使用する場合、onclick
関数がfalseを返すことを確認してイベントをキャンセルできます...関数がラップされます...したがって、onclick="return myHandler();"
またはonclick="myHandler(); return false;"
などを実行して、onclickがfalseを返すようにする必要があります。getEventListeners
APIを使用して、イベントリスナーがどのように見えるかを確認して、推測を避け、イベントハンドラーが期待どおりに動作していないかどうかを確認できます。この例は、<a>
リンクを持つclick
イベントに固有のものですが、ほとんどのイベントタイプに一般化できます。
クラスjs-some-link-hook
のアンカー(リンク)があり、モーダルを開き、ページナビゲーションが発生しないようにします。
以下の例は、MacOS Mojaveのgoogle chrome(71)で実行されました。
1つの大きな落とし穴は、onclick=functionName
がaddEventListener
を使用するのと同じ動作であると想定していることです。
function eventHandler (event) {
// want to prevent link navigation
alert('eventHandler ran');
return false;
}
function addEventListenerToElement () {
var link = document.querySelector('.js-some-link-hook');
link.setAttribute('onclick', eventHandler);
}
addEventListenerToElement();
次に、ブラウザーのdevtoolsコンソールで実行します。
var el = document.querySelector('a.js-some-link-hook'),
listener = getEventListeners(el).click[0].listener;
console.log(''+listener); // to avoid truncation of output
...そしてあなたが見る:
function onclick(event) {
function t(n){return alert("eventHandler ran"),!1}
}
これはまったく機能しません。 onclick=
を使用する場合、ハンドラー関数は別の関数にラップされます。この場合、関数定義は含まれていますが、呼び出されずに関数参照を指定したために呼び出されていないことがわかります。さらに、関数が呼び出されて関数がfalseを返したとしても、onclick関数はそのfalse値を返さないことがわかります。これはイベントを「キャンセル」するために必要です。動作させるには、return myHandlerFunc();
をonclick関数でラップする必要があります。
これがどのように機能するかがわかったので、コードを変更して、必要な処理を実行できます。説明のための奇妙な例(このコードは使用しないでください):
function eventHandler (event) {
// want to prevent link navigation
alert('eventHandler ran');
return false;
}
function addEventListenerToElement () {
var link = document.querySelector('.js-some-link-hook');
link.setAttribute('onclick', 'return ('+eventHandler+')();');
}
addEventListenerToElement();
EventHandler関数の定義を文字列にラップしたことがわかります。具体的には、先頭にreturnステートメントがある自己実行関数。
再びchrome devtoolsコンソールで:
var el = document.querySelector('a.js-some-link-hook'),
listener = getEventListeners(el).click[0].listener;
console.log(''+listener); // to avoid truncation of output
...ショー:
function onclick(event) {
return (function t(e){return alert("eventHandler ran"),!1})();
}
...そう、それはうまくいくはずです。 return false
(ミニフィケーションの実行のため、!1
、申し訳ありません)。確かに、リンクをクリックするとアラートが表示され、ページを移動したり更新したりすることはありません。
function eventHandler (event) {
// want to prevent link navigation
alert('eventHandler ran');
return false;
}
function addEventListenerToElement () {
var link = document.querySelector('.js-some-link-hook');
link.addEventListener('click', eventHandler, false);
}
addEventListenerToElement();
ブラウザー開発ツール:
var el = document.querySelector('a.js-some-link-hook'),
listener = getEventListeners(el).click[0].listener;
console.log(''+listener); // to avoid truncation of output
結果:
function e(n){return alert("eventHandler ran"),!1}
だからあなたはすでに違いを見ることができます。 onclick関数にラップされていません。したがって、return false
(縮小のためreturn !1
)はここの最上位にあり、以前のように余分なreturnステートメントを追加することを心配する必要はありません。
動作するはずです。リンクをクリックすると、アラートが表示されます。アラートを閉じると、ページがナビゲート/更新されます。 ieイベントはfalseを返すことでキャンセルされませんでした。
仕様を検索すると(下のリソースを参照)、addEventListenerのコールバック/ハンドラー関数は戻り値の型をサポートしていないことがわかります。必要なものは何でも返すことができますが、インターフェイスの一部ではないため、効果はありません。
解決策:return false;
の代わりにevent.preventDefault()
を使用しています...
function eventHandler (event) {
// want to prevent link navigation
event.preventDefault();
alert('eventHandler ran');
}
function addEventListenerToElement () {
var link = document.querySelector('.js-some-link-hook');
link.addEventListener('click', eventHandler, false);
}
addEventListenerToElement();
ブラウザ開発ツール...
var el = document.querySelector('a.js-some-link-hook'),
listener = getEventListeners(el).click[0].listener;
console.log(''+listener); // to avoid truncation of output
与える...
function n(e){e.preventDefault(),alert("eventHandler ran")}
...予想通り。
テスト:アラートを取得します。アラートを閉じます。 Noページナビゲーションまたは更新...これが必要です。
Html5仕様( https://www.w3.org/TR/html5/webappapis.html#events )は、例でonclick
とaddEventListener
の両方を使用し、次のように言っているため、物事を混乱させています。
イベントハンドラーHおよびイベントオブジェクトEのイベントハンドラー処理アルゴリズムは次のとおりです。
...
- 次のように戻り値を処理します。
...
戻り値がWeb IDLブールfalse値の場合、イベントをキャンセルします。
したがって、return false
はaddEventListener
とonclick
の両方のイベントをキャンセルすることを意味するようです。
しかし、リンクされたevent-handler
の定義を見ると、次のように表示されます:
イベントハンドラには名前があり、常に「on」で始まり、その後に対象となるイベントの名前が続きます。
...
イベントハンドラは、2つの方法のいずれかで公開されます。
すべてのイベントハンドラーに共通する最初の方法は、イベントハンドラーIDL属性としての方法です。
2番目の方法は、イベントハンドラーのコンテンツ属性としてです。 HTML要素のイベントハンドラーとWindowオブジェクトのイベントハンドラーの一部は、この方法で公開されます。
https://www.w3.org/TR/html5/webappapis.html#event-handler
したがって、イベントをキャンセルするreturn false
は、実際にはonclick
(または一般にon*
)イベントハンドラーにのみ適用され、異なるAPIを持つaddEventListener
を介して登録されたイベントハンドラーには適用されないようです。 addEventListener APIはhtml5仕様ではカバーされておらず、on*
イベントハンドラーのみが対象であるため、例でそれにこだわって違いを明確に示した場合、混乱が少なくなります。