サーチ…
備考
jQueryは内部的にaddEventListener関数を介してイベントを処理します。つまり、同じDOM要素に対して同じイベントに複数の関数をバインドすることは完全に合法です。
イベントハンドラのアタッチとデタッチ
イベントハンドラをアタッチする
バージョン1.7以降、jQueryにはイベントAPIの.on()
ます。これにより、現在選択されているjQuery要素に標準のJavaScriptイベントまたはカスタムイベントをバインドできます。 .click()
などのショートカットがありますが、 .on()
はさらに多くのオプションを提供します。
HTML
<button id="foo">bar</button>
jQuery
$( "#foo" ).on( "click", function() {
console.log( $( this ).text() ); //bar
});
イベントハンドラをデタッチする
もちろん、jQueryオブジェクトからイベントを切り離すこともできます。これは.off( events [, selector ] [, handler ] )
を使って.off( events [, selector ] [, handler ] )
。
HTML
<button id="hello">hello</button>
jQuery
$('#hello').on('click', function(){
console.log('hello world!');
$(this).off();
});
ボタン$(this)
をクリックすると、現在のjQueryオブジェクトが参照され、添付されているすべてのイベントハンドラが削除されます。削除するイベントハンドラを指定することもできます。
jQuery
$('#hello').on('click', function(){
console.log('hello world!');
$(this).off('click');
});
$('#hello').on('mouseenter', function(){
console.log('you are about to click');
});
この場合、 mouseenter
イベントは、クリックした後も引き続き機能します。
委託されたイベント
例を見てみましょう。ここでは、非常に簡単なHTMLの例を示します。
HTMLの例
<html>
<head>
</head>
<body>
<ul>
<li>
<a href="some_url/">Link 1</a>
</li>
<li>
<a href="some_url/">Link 2</a>
</li>
<li>
<a href="some_url/">Link 3</a>
</li>
</ul>
</body>
</html>
問題
この例では、すべての<a>
要素にイベントリスナーを追加します。問題は、この例のリストが動的であることです。 <li>
時間の経過とともにエレメントが追加および削除されます。しかし、ページは変更の間に更新されないため、リンクオブジェクト(つまり$('a').click()
)に単純なクリックイベントリスナーを使用することができ$('a').click()
。
私たちが持っている問題は、出入りする<a>
要素にイベントを追加する方法です。
背景情報 - イベント伝播
委任されたイベントは、イベントの伝達(イベントのバブルと呼ばれることが多い)のためにのみ可能です。イベントが発生すると、いつでも(ドキュメントルートに)バブルされます。彼らは、その名の「委任」のイベント、非変更祖先要素にイベントの処理を委任します。
したがって、上記の例では、 <a>
要素のリンクをクリックすると、次の要素の「クリック」イベントがこの順序でトリガーされます。
- a
- リ
- ul
- 体
- html
- ドキュメントルート
溶液
どのようなイベントのバブリングが起こっているかを知ることで、私たちはHTMLを通じて伝播している希望のイベントの1つをキャッチできます。
この例では、 <ul>
要素は動的でないため、キャッチするのに適しています。
$('ul').on('click', 'a', function () {
console.log(this.href); // jQuery binds the event function to the targeted DOM element
// this way `this` refers to the anchor and not to the list
// Whatever you want to do when link is clicked
});
上:
- このイベントリスナーの受信者である 'ul'があります
- 最初のパラメータ( 'click')は、検出しようとしているイベントを定義します。
- 2番目のパラメータ( 'a')は、イベントの発信元 (このイベントリスナの受信者ulの下にあるすべての子要素)の宣言に使用されます。
- 最後に、第3のパラメータは、第1および第2のパラメータの要件が満たされた場合に実行されるコードです。
ソリューションの仕組みの詳細
- ユーザーが
<a>
要素をクリックする - それは
<a>
要素のclickイベントをトリガーします。 - このイベントは、ドキュメントルートに向けてバブリングを開始します。
- イベントは最初に
<li>
要素をバブルし、<ul>
要素をバブルします。 -
<ul>
要素にイベントリスナーが関連付けられているため、イベントリスナーが実行されます。 - イベントリスナーは、最初にトリガーイベントを検出します。バブリングイベントは「クリック」で、リスナーは「クリック」しています。パスです。
- リスナーチェックは、バブルチェーン内の各項目に2番目のパラメータ( 'a')を一致させようとします。チェーンの最後の項目が 'a'であるため、これはフィルタに一致し、これもパスです。
- 三番目のパラメータのコードは、それはだとしてマッチしたアイテムを使用して実行され
this
。この関数にstopPropagation()
呼び出しが含まれていない場合、イベントはルート(document
)に向かって上方に伝播し続けます。
注:適切で変化しない適切な祖先が利用可能でない/便利でない場合は、 document
を使用する必要がありdocument
。習慣として、以下の理由から'body'
を使用しないでください:
-
body
は、マウスイベントがバブルしないことを意味するスタイリングと関係するバグがあります。これはブラウザに依存し、計算されたボディの高さが0の場合(たとえば、すべての子要素が絶対位置を持つ場合など)に発生する可能性があります。マウスイベントは常にdocument
バブルしdocument
。 -
document
常にスクリプトに存在するため、委託されたハンドラをDOM対応のハンドラ以外のdocument
添付して、それが動作することを確認してください。
ドキュメント読み込みイベント.load()
イメージやPDFなど、特定のリソースがロードされるまでスクリプトを待機させたい場合は、 .on( "load", handler)
ショートカットのためのショートカットである.load()
使用できます。
HTML
<img src="image.jpeg" alt="image" id="image">
jQuery
$( "#image" ).load(function() {
// run script
});
IDを使用せずに繰り返し要素のイベント
問題
特定のインスタンスで何かをするためにイベントが発生したかを知る必要がある一連の繰り返し要素がページにあります。
溶液
- すべての共通要素に共通のクラスを与える
- イベントリスナーをクラスに適用します。
this
内部イベントハンドラは、イベントが発生した一致セレクタ要素です -
this
インスタンスを開始することによって、最も外側の反復コンテナに移動します。 - そのコンテナ内の
find()
使用して、そのインスタンスに固有の他の要素を分離する
HTML
<div class="item-wrapper" data-item_id="346">
<div class="item"><span class="person">Fred</span></div>
<div class="item-toolbar">
<button class="delete">Delete</button>
</div>
</div>
<div class="item-wrapper" data-item_id="393">
<div clss="item"><span class="person">Wilma</span></div>
<div class="item-toolbar">
<button class="delete">Delete</button>
</div>
</div>
jQuery
$(function() {
$('.delete').on('click', function() {
// "this" is element event occured on
var $btn = $(this);
// traverse to wrapper container
var $itemWrap = $btn.closest('.item-wrapper');
// look within wrapper to get person for this button instance
var person = $itemWrap.find('.person').text();
// send delete to server and remove from page on success of ajax
$.post('url/string', { id: $itemWrap.data('item_id')}).done(function(response) {
$itemWrap.remove()
}).fail(function() {
alert('Ooops, not deleted at server');
});
});
});
オリジナルイベント
jQueryイベントでは利用できないプロパティが存在することがあります。基になるプロパティにアクセスするには、 Event.originalEvent
を使用しますEvent.originalEvent
スクロール方向を取得する
$(document).on("wheel",function(e){
console.log(e.originalEvent.deltaY)
// Returns a value between -100 and 100 depending on the direction you are scrolling
})
jQueryを使用して特定のイベントをオンまたはオフに切り替えます。 (名前付きリスナー)
以前に登録したすべてのリスナーをオフにしたい場合があります。
//Adding a normal click handler
$(document).on("click",function(){
console.log("Document Clicked 1")
});
//Adding another click handler
$(document).on("click",function(){
console.log("Document Clicked 2")
});
//Removing all registered handlers.
$(document).off("click")
このメソッドの問題は、他のプラグインなどによってdocument
上にバインドされたすべてのリスナーも削除されることです。
多くの場合、私たちだけが添付したすべてのリスナーを切り離したいと思っています。
これを実現するために、名前付きリスナーを、
//Add named event listener.
$(document).on("click.mymodule",function(){
console.log("Document Clicked 1")
});
$(document).on("click.mymodule",function(){
console.log("Document Clicked 2")
});
//Remove named event listener.
$(document).off("click.mymodule");
これにより、他のクリックリスナーが誤って変更されることがなくなります。