JQuery найти обработчики событий, зарегистрированных с объектом - PullRequest
524 голосов
/ 25 марта 2010

Мне нужно найти, какие обработчики событий зарегистрированы для объекта.

Например:

$("#el").click(function() {...});
$("#el").mouseover(function() {...});

$("#el") имеет нажатие и указатель мыши зарегистрирован.

Есть ли функция, чтобы узнать это и, возможно, перебрать обработчики событий?

Если это невозможно для объекта jQuery с помощью надлежащих методов, возможно ли это для простого объекта DOM?

Ответы [ 14 ]

655 голосов
/ 25 марта 2010

Начиная с jQuery 1.8, данные событий больше не доступны из «публичного API» для данных. Прочитайте это сообщение в блоге jQuery . Теперь вы должны использовать это вместо:

jQuery._data( elem, "events" );

elem должен быть элементом HTML, а не объектом jQuery или селектором.

Обратите внимание, что это внутренняя, «частная» структура, и ее не следует изменять. Используйте это только для целей отладки.

В старых версиях jQuery вам, возможно, придется использовать старый метод:

jQuery( elem ).data( "events" );
78 голосов
/ 25 марта 2010

Вы можете сделать это, просканировав события (начиная с 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>
35 голосов
/ 05 июля 2012

В jQuery 1.8+ это больше не будет работать, поскольку внутренние данные помещены в другой объект.

Последний неофициальный (но работает и в предыдущих версиях, по крайней мере, в 1.7.2) способ сделать это сейчас - $._data(element, "events")

Подчеркивание ("_") - вот что здесь имеет значение. Внутренне он вызывает $.data(element, name, null, true), последний (четвертый) параметр является внутренним ("pvt").

32 голосов
/ 21 января 2014

Бесстыдная вилка, но вы можете использовать findHandlerJS

Чтобы использовать его, вам просто нужно включить findHandlersJS (или просто скопировать и вставить необработанный код JavaScript в окно консоли Chrome) и указать тип события и селектор jquery для элементов, которые вы заинтересованы в.

Для вашего примера вы можете быстро найти упомянутые вами обработчики событий, выполнив

findEventHandlers("click", "#el")
findEventHandlers("mouseover", "#el")

Вот что возвращается:

  • элемент
    Фактический элемент, в котором обработчик события был зарегистрирован в
  • События
    Массив с информацией об обработчиках событий jquery для интересующего нас типа события (например, щелчок, изменение и т. Д.)
    • обработчик
      Фактический метод обработчика событий, который вы можете увидеть, щелкнув его правой кнопкой мыши и выбрав Показать определение функции
    • селектор
      Селектор для делегированных событий. Для прямых событий будет пусто.
    • цели
      Список с элементами, на которые нацелен этот обработчик событий. Например, для делегированного обработчика событий, который зарегистрирован в объекте документа и предназначается для всех кнопок на странице, это свойство будет перечислять все кнопки на странице. Вы можете навести их и увидеть, что они выделены хромом.

Вы можете попробовать это здесь

12 голосов
/ 26 июля 2012

Я использую плагин eventbug для firebug для этой цели.

9 голосов
/ 12 ноября 2014

Я объединил оба решения из @jps в одну функцию:

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.

5 голосов
/ 03 апреля 2013

По состоянию на 1.9 не существует документированного способа получения событий, кроме использования плагина Migrate для восстановления старого поведения. Вы можете использовать метод _.data (), как упоминает jps, но это внутренний метод. Так что просто сделайте правильно и используйте плагин Migrate, если вам нужна эта функциональность.

Из документации jQuery по .data("events")

До версии 1.9 .data ("события") можно было использовать для получения jQuery недокументированная структура данных внутреннего события для элемента, если нет других Код определил элемент данных с именем «события». Это особенное дело было удалено в 1.9. Нет открытого интерфейса для извлечения это внутренняя структура данных, и она остается недокументированной. Тем не мение, плагин jQuery Migrate восстанавливает это поведение для кода, который зависит на это.

3 голосов
/ 07 ноября 2017

Я создал пользовательский селектор 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)")

Это вернет элементы, к которым прикреплен обработчик кликов.

2 голосов
/ 30 августа 2018

Для проверки событий на элементе:

var events = $._data(element, "events")

Обратите внимание, что это будет работать только с прямыми обработчиками событий, если вы используете $ (document) .on ("имя-события", "jq-селектор", 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])
2 голосов
/ 07 мая 2014

В современном браузере с ECMAScript 5.1 / Array.prototype.map вы также можете использовать

jQuery._data(DOCUMENTELEMENT,'events')["EVENT_NAME"].map(function(elem){return elem.handler;});

в консоли браузера, которая будет печатать источник обработчиков, разделенных запятой. Полезно для просмотра того, что все работает на определенном событии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...