オブジェクトにどのイベントハンドラが登録されているかを調べる必要があります。
例えば:
$("#el").click(function() {...});
$("#el").mouseover(function() {...});
$("#el")
には click と mouseover が登録されています。
それを見つけ出して、おそらくイベントハンドラを反復処理する関数はありますか?
それが適切な方法でjQueryオブジェクト上で不可能であるならば、それは普通のDOMオブジェクト上で可能ですか?
JQuery 1.8以降、イベントデータはデータ用の「public API」から利用できなくなりました。 このjQueryブログ投稿 を読んでください。代わりにこれを使用してください。
jQuery._data( elem, "events" );
elem
はjQueryオブジェクトやセレクタではなくHTML要素であるべきです。
注意してください、これは内部の 'プライベート'構造であり、変更するべきではありません。デバッグ目的でのみ使用してください。
古いバージョンのjQueryでは、古いメソッドを使う必要があるかもしれません。
jQuery( elem ).data( "events" );
これを行うには、イベントをクロールします(jQuery 1.8以降)。
$.each($._data($("#id")[0], "events"), function(i, event) {
// i is the event type, like "click"
$.each(event, function(j, h) {
// h.handler is the function being called
});
});
これがあなたが遊ぶことができる例です:
$(function() {
$("#el").click(function(){ alert("click"); });
$("#el").mouseover(function(){ alert("mouseover"); });
$.each($._data($("#el")[0], "events"), function(i, event) {
output(i);
$.each(event, function(j, h) {
output("- " + h.handler);
});
});
});
function output(text) {
$("#output").html(function(i, h) {
return h + text + "<br />";
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="el">Test</div>
<code>
<span id="output"></span>
</code>
JQuery 1.8以降の場合、内部データは別のオブジェクトに配置されるため、これは機能しなくなります。
最新の非公式な(しかし、少なくとも1.7.2では以前のバージョンでも動作する)方法は、 - $._data(element, "events")
である。
ここで違いが生じるのは、アンダースコア( "_")です。内部的には$.data(element, name, null, true)
を呼び出しています。最後の(4番目の)パラメータは内部のもの( "pvt")です。
恥知らずなプラグ、しかしあなたは findHandlerJS /を使うことができます
それを使用するには、 findHandlersJS を含めるか(または 生のjavascriptコード をchromeのコンソールウィンドウにコピー&ペーストして)、関心のある要素のイベントタイプとjqueryセレクタを指定するだけです。
あなたの例では、あなたはすぐにあなたが言及したイベントハンドラを見つけることができます
findEventHandlers("click", "#el")
findEventHandlers("mouseover", "#el")
これが返されるものです:
あなたはそれを試すことができます ここ
この目的のためにfirebugに eventbug pluginを使います。
@jpsから両方の解決策を1つの関数にまとめました。
jQuery.fn.getEvents = function() {
if (typeof(jQuery._data) == 'function') {
return jQuery._data(this.get(0), 'events') || {};
} else if (typeof(this.data) == 'function') { // jQuery version < 1.7.?
return this.data('events') || {};
}
return {};
};
ただし、この関数はjQuery自体を使用して設定されたイベントのみを返すことに注意してください。
1.9以降、Migrateプラグインを使用して古い動作を復元する以外に、イベントを取得するための文書化された方法はありません。 jpsが言及しているように_.data()メソッドを使用することもできますが、それは内部メソッドです。この機能が必要な場合は、正しいことをしてMigrateプラグインを使用してください。
.data("events")
のjQueryドキュメントから
1.9より前では、他のコードが "events"という名前のデータ要素を定義していなかった場合、.data( "events")を使用して要素のjQueryの文書化されていない内部イベントデータ構造を取得できます。この特別なケースは1.9で削除されました。この内部データ構造を取得するためのパブリックインターフェイスはなく、ドキュメント化されていません。ただし、jQuery Migrateプラグインはそれに依存するコードに対してこの動作を復元します。
割り当てられたイベントハンドラのjQueryキャッシュと、それらを追加するためのネイティブメソッドを使用する要素の両方をチェックするカスタムjQueryセレクタを作成しました。
(function($){
$.find.selectors[":"].event = function(el, pos, match) {
var search = (function(str){
if (str.substring(0,2) === "on") {str = str.substring(2);}
return str;
})(String(match[3]).trim().toLowerCase());
if (search) {
var events = $._data(el, "events");
return ((events && events.hasOwnProperty(search)) || el["on"+search]);
}
return false;
};
})(jQuery);
例:
$(":event(click)")
クリックハンドラがアタッチされている要素が返されます。
ECMAScript 5.1/Array.prototype.map
を使用した最新のブラウザでは、次のものも使用できます。
jQuery._data(DOCUMENTELEMENT,'events')["EVENT_NAME"].map(function(elem){return elem.handler;});
ブラウザのコンソールでは、ハンドラのソースがカンマ区切りで出力されます。特定のイベントで何が実行されているのかを一目で確認するのに役立ちます。
要素のイベントを確認するには
var events = $._data(element, "events")
$(document).on( "event-name"、 "jq-selector"、function(){// logic})を使用している場合、これは直接イベントハンドラでのみ機能します。この答えの一番下にあるgetEvents関数
例えば:
var events = $._data(document.getElementById("myElemId"), "events")
または
var events = $._data($("#myElemId")[0], "events")
完全な例:
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" type="text/javascript"></script>
<script>
$(function() {
$("#textDiv").click(function() {
//Event Handling
});
var events = $._data(document.getElementById('textDiv'), "events");
var hasEvents = (events != null);
});
</script>
</head>
<body>
<div id="textDiv">Text</div>
</body>
</html>
$(document).onと共にインストールされる動的リスナーを含む、より完全なチェック方法
function getEvents(element) {
var elemEvents = $._data(element, "events");
var allDocEvnts = $._data(document, "events");
for(var evntType in allDocEvnts) {
if(allDocEvnts.hasOwnProperty(evntType)) {
var evts = allDocEvnts[evntType];
for(var i = 0; i < evts.length; i++) {
if($(element).is(evts[i].selector)) {
if(elemEvents == null) {
elemEvents = {};
}
if(!elemEvents.hasOwnProperty(evntType)) {
elemEvents[evntType] = [];
}
elemEvents[evntType].Push(evts[i]);
}
}
}
}
return elemEvents;
}
使用例
getEvents($('#myElemId')[0])
私は答えの多くが興味深いと言わなければなりません、しかし最近私は同様の問題を抱えていました、そして、解決策はDOMの道を進むことによって非常に簡単でした。それはあなたが反復するのではなく、あなたが必要とする出来事に直接狙いを定めているという点で異なっています、しかし以下で私はより一般的な答えを与えます。
私は続けて画像を持っていました:
<table>
<td><tr><img class="folder" /></tr><tr>...</tr></td>
</table>
その画像にはclickイベントハンドラが添付されています。
imageNode.click(function () { ... });
私の意図は、クリック可能な領域を行全体に拡大することでしたので、最初にすべての画像と相対行を取得しました。
tableNode.find("img.folder").each(function () {
var tr;
tr = $(this).closest("tr");
// <-- actual answer
});
実際のanwer 行で、私はちょうど次のようにして、元の質問に答えました。
tr.click(this.onclick);
そこで、DOM要素から直接イベントハンドラを取得し、それをjQuery clickイベントハンドラに入れました。魅力のように働きます。
さて、一般的な場合に。以前のjQuery以前の時代では、 Douglas Crockford によって以下の2つのシンプルで強力な関数を使用してすべてのイベントを生成できました。
function walkTheDOM(node, func)
{
func(node);
node = node.firstChild;
while (node)
{
walkTheDOM(node, func);
node = node.nextSibling;
}
}
function purgeEventHandlers(node)
{
walkTheDOM(node, function (n) {
var f;
for (f in n)
{
if (typeof n[f] === "function")
{
n[f] = null;
}
}
});
}
クロムを使用している場合は、jqueryデバッガプラグインを試してください。 https://chrome.google.com/webstore/detail/jquery-debugger/dbhhnnnpaeobfddmlalhnehgclcmjimi?hl=ja
イベントは以下の方法で取得できます。
jQuery(elem).data('events');
またはjQuery 1.8以降:
jQuery._data(elem, 'events');
注: $('selector').live('event', handler)
を使用してバインドされたイベントは、以下を使用して取得できます。
jQuery(document).data('events')
もう1つの方法は、jQueryを使用して要素を取得してから実際のJavascriptを実行し、イベントハンドラを取得および設定して再生することです。例えば:
var oldEventHandler = $('#element')[0].onclick;
// Remove event handler
$('#element')[0].onclick = null;
// Switch it back
$('#element')[0].onclick = oldEventHandler;