JQueryを使用して、DOMツリー全体で変更をリッスンすることは可能ですか?
私の特定の問題:html要素でtitle
を実行すると、hover
属性の内容をスタイリッシュな方法で表示する 'ツールチップ'関数があります。ただし、ホバーすると、標準でブラウザーはtitle
を独自のボックスにレンダリングします。それを抑えたいのですが。したがって、最初にページがロードされたときにtitle
属性の内容をカスタム(HTML5)のdata-title
属性に移動すると、ツールチップ関数がdata-title
で機能するようになります。
問題は、後でHTMLを動的に追加/削除/変更する可能性があるため、これらの要素を「再バインド」する必要があることです。これらのタイトル属性をもう一度変更してください。そのような変更をリッスンし、要素を自動的に再バインドするイベントリスナーがあったらいいですね。
私の推測では、DOM変異イベントをリッスンしたいと思います。 DOMミューテーションイベントによって、マウスクリックなどの通常のJavaScriptイベントと同じように行うことができます。
これを参照してください: W3 MutationEvent
例:
$("element-root").bind("DOMSubtreeModified", "CustomHandler");
[トニー会員の調査に応じて編集]
したがって、追加のコードがなければ、これは少し盲目的なショットですが、私にはここで2つのことを考える必要があるように見えます。1。デフォルトのブラウザーツールチップの動作。 2.更新される可能性のあるDOM、およびカスタムツールチップが機能し続ける機能。
#1について: カスタムイベントを要素にバインドするときに、 これは正しく動作しません。したがって、「title」属性を使い続けるための回避策は、値を取得し、それをデータオブジェクトにプッシュし(event.preventDefault()
を使用して、ツールチップが表示されないようにすることができます。$.data()
関数)、次に空の文字列でタイトルをnullにすることです(removeAttrに一貫性がありません)。 。次に、mouseleaveで、データオブジェクトから値を取得し、それをタイトルにプッシュします。このアイデアはここから来ます: jQueryでブラウザーのツールチップを無効にする方法?
#2に関して:DOMの変更を再バインドする代わりに、破棄されることが決して予想されないリスナー要素に一度バインドするだけで済みます。通常、これはある種のコンテナー要素ですが、本当にすべてを含むコンテナーが必要な場合は、document
(現在は非推奨の.live()
に近い)にすることもできます。これは、私が考案した偽のマークアップを使用するサンプルです。
var container = $('.section');
container.on('mouseenter', 'a', function() {
var $this = $(this);
var theTitle = $this.attr('title');
$this.attr('title', '');
$('#notatooltip').html(theTitle);
$.data(this, 'title', theTitle);
});
container.on('mouseleave', 'a', function() {
$('#notatooltip').html('');
var $this = $(this);
var storedTitle = $.data(this, 'title');
$this.attr('title', storedTitle);
});
私の非現実的なマークアップ(この例のみ)はここにあります:
<div class="section">
<a href="#" title="foo">Hover this foo!</a>
<div id="notatooltip"></div>
</div>
そしてフィドルがここにあります: http://jsfiddle.net/GVDqn/ またはいくつかの健全性チェック: http://jsfiddle.net/GVDqn/1/
これを行うにはもっと最適な方法があると思います(1つのセレクターで2つの別々のイベントに2つの別々の関数をバインドできるかどうかは正直に調査しませんでした)。
DOMの変更に基づいて再バインドする必要はありません。委任されたリスナーが自動的に処理します。また、デフォルトのツールチップ機能を防止するだけで防止できるはずです。
Greg Pettitが指摘したように、要素にはon()関数を使用する必要があります。
これにより、セレクターをイベントにバインドでき、セレクターによって返されたオブジェクトが利用可能になると、jQueryはこのイベントハンドラーを追加します。
マウスオーバーイベントで関数を起動し、クラスが* field_title *のすべての要素で関数を起動したい場合は、次のようにします。
$('.field_title').bind('mouseenter', function() { doSomething(); });
これは、クラス* field_title *を持つオブジェクトのマウスオーバーイベントでトリガーされ、関数doSomething()を実行します。
理にかなっていると思います:)