[解決済み] addEventListenerとonclickの比較
質問
とはどう違うのですか?
addEventListener
と
onclick
?
var h = document.getElementById("a");
h.onclick = dothing1;
h.addEventListener("click", dothing2);
上記のコードは別の.jsファイルに一緒に存在し、どちらも完全に動作します。
解決するには?
どちらも正しいのですが、それ自体がベストというわけではありませんし、開発者が両方のアプローチを選択した理由もあるでしょう。
イベントリスナー(addEventListenerとIEのattachEvent)
Internet Explorer の初期バージョンは、他の多くのブラウザとは異なる方法で javascript を実装しています。 9より前のバージョンでは
attachEvent
[
ドク
] メソッドのようになります。
element.attachEvent('onclick', function() { /* do stuff here*/ });
他のほとんどのブラウザ(IE 9以降を含む)では、以下のようになります。
addEventListener
[
ドク
] のようになります。
element.addEventListener('click', function() { /* do stuff here*/ }, false);
この方法( DOMレベル2イベント ) を使用すると、理論的には1つの要素に無制限の数のイベントを付けることができます。唯一の現実的な制限は、クライアントサイドのメモリとその他のパフォーマンスに関するもので、これはブラウザごとに異なります。
上記の例では、無名関数[ ドクター ]. また、関数リファレンスを使用してイベントリスナーを追加することもできます[ 。 doc またはクロージャ[ doc ]:
var myFunctionReference = function() { /* do stuff here*/ }
element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);
のもう一つの重要な特徴は
addEventListener
は最後のパラメータで、リスナーがバブリングイベントにどのように反応するかを制御します[ ]。
ドクター
]. この例では false を渡していますが、これはおそらく95%のユースケースで標準的なものです。に相当する引数はありません。
attachEvent
またはインライン・イベントを使用する場合。
インラインイベント(HTML onclick=""プロパティとelement.onclick)
javascriptをサポートしているすべてのブラウザでは、イベントリスナーをインラインで、つまりHTMLコードの中に置くことができます。 おそらくこれを見たことがあるはずです。
<a id="testing" href="#" onclick="alert('did stuff inline');">Click me</a>
経験豊富な開発者の多くはこの方法を敬遠しますが、シンプルで直接的な方法で仕事はできます。クロージャや無名関数は使えないし(ハンドラ自体は無名関数の一種ですが)、スコープの制御も制限されます。
もう1つの方法ですが
element.onclick = function () { /*do stuff here */ };
...は、インラインJavaScriptと同等ですが、(HTMLではなくスクリプトを書いているので)スコープをより制御でき、匿名関数、関数参照、クロージャを使用できる点が異なります。
インラインイベントの大きな欠点は、前述のイベントリスナーとは異なり、割り当てられるインラインイベントは1つだけであることです。インラインイベントは要素の属性/プロパティとして保存されます[ ]。 doc つまり、上書きすることができるのです。
例として
<a>
を上記のHTMLから削除します。
var element = document.getElementById('testing');
element.onclick = function () { alert('did stuff #1'); };
element.onclick = function () { alert('did stuff #2'); };
... 要素をクリックすると
だけ
の最初の割り当てを上書きしています。
onclick
プロパティを2番目の値で上書きし、元のインラインHTMLの
onclick
プロパティもあります。ここで確認してみてください。
http://jsfiddle.net/jpgah/
.
大まかに言うと インラインイベントを使用しない . 特定のユースケースがあるかもしれませんが、そのユースケースが100%ないと確信できるのであれば、インラインイベントは使用しませんし、使用すべきではありません。
モダンJavascript(Angularなど)
この回答が最初に投稿されて以来、Angularのようなjavascriptフレームワークがはるかに普及してきました。Angularのテンプレートでは、このようなコードを目にすることができます。
<button (click)="doSomething()">Do Something</button>
これはインラインイベントのように見えますが、そうではありません。このタイプのテンプレートは、裏側でイベントリスナーを使用する、より複雑なコードに変換されます。私がイベントに関してここで書いたことはすべてそのまま適用されますが、少なくとも1つの層によって細かい部分から切り離されます。しかし、最新のJSフレームワークのベストプラクティスでは、このようなコードをテンプレートに記述することになっている場合、インラインイベントを使用しているように感じないでください -- そうではありません。
どれが一番いいの?
この問題は、ブラウザの互換性と必要性の問題です。1つの要素に複数のイベントをアタッチする必要があるのでしょうか?将来的にはそうなるのでしょうか?attachEventとaddEventListenerは必要です。そうでない場合は、インライン・イベントで事足りるように思えるかもしれませんが、可能性は低いかもしれませんが、少なくとも予測可能な未来に備える方がずっとよいでしょう。JSベースのイベントリスナーに移行しなければならない可能性があるのだから、そこから始めたほうがいい。インライン・イベントは使わないでください。
jQuery や他の javascript フレームワークは、DOM レベル 2 イベントの異なるブラウザの実装を汎用モデルにカプセル化するので、IEの履歴を反面教師として気にすることなく、クロスブラウザに準拠したコードを書くことができます。 jQuery を使用した同じコードで、すべてクロスブラウザに対応し、ロックする準備ができています。
$(element).on('click', function () { /* do stuff */ });
しかし、このためだけにフレームワークを購入する必要はありません。古いブラウザに対応するための小さなユーティリティを自作するのは簡単です。
function addEvent(element, evnt, funct){
if (element.attachEvent)
return element.attachEvent('on'+evnt, funct);
else
return element.addEventListener(evnt, funct, false);
}
// example
addEvent(
document.getElementById('myElement'),
'click',
function () { alert('hi!'); }
);
試してみてください。 http://jsfiddle.net/bmArj/
これらのことを考慮すると、あなたが見ているスクリプトが他の方法で(あなたの質問に示されていないコードで)ブラウザの違いを考慮したのでない限りは、この部分の
addEventListener
は、IE のバージョンが 9 未満の場合、動作しないことがあります。
ドキュメントと関連する読み物
関連
-
vueネットワークリクエストソリューション ネイティブネットワークリクエストとjsネットワークリクエストライブラリ
-
JavaScriptのクロージャの説明
-
[解決済み】event.stopPropagationとevent.preventDefaultの違いは何ですか?
-
[解決済み] substrとsubstringの違いは何ですか?
-
[解決済み] Node.jsのmodule.exportsとexportsの比較
-
[解決済み] RecyclerView onClick
-
[解決済み] 子アンカーがクリックされたときに、親のonclickイベントが発生しないようにするにはどうすればよいですか?
-
[解決済み] JasmineのJavaScriptテスト - toBeとtoEqualの比較
-
[解決済み】addEventListenerリスナー関数に引数を渡すには?
-
[解決済み】application/x-javascriptとtext/javascriptのコンテンツタイプの違いについて
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
fetch ネットワークリクエストラッパーの説明例
-
要素ツリー制御によるvueTreeテーブル
-
JavaScriptにおけるマクロタスクとミクロタスクの詳細
-
Vueでルートネスティングを実装する例
-
vueのプロジェクトでモックを使用する方法を知っていますか?
-
Vueの「データを聴く」原則を解説
-
[解決済み】SyntaxError: JSONの位置1に予期しないトークンoがある。
-
[解決済み】JavaScriptの配列でforEachが関数でない不具合
-
[解決済み】React-Redux: アクションはプレーンオブジェクトでなければならない。非同期アクションにはカスタムミドルウェアを使用する
-
Uncaught TypeError: null のプロパティ 'offsetHeight' を読み取れませんでした。