Programming

jQuery는 객체에 등록 된 이벤트 핸들러를 찾습니다.

procodes 2020. 2. 10. 22:32
반응형

jQuery는 객체에 등록 된 이벤트 핸들러를 찾습니다.


객체에 등록 된 이벤트 핸들러를 찾아야합니다.

예를 들면 다음과 같습니다.

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

$("#el")클릭 하고 마우스 오버 등록.

그것을 알아 내고 이벤트 처리기를 반복 할 수있는 기능이 있습니까?

적절한 메소드를 통해 jQuery 객체에서 가능하지 않은 경우 일반 DOM 객체에서 가능합니까?


jQuery 1.8부터는 "공용 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 를 포함 시키 거나 ( 원시 자바 스크립트 코드 를 크롬의 콘솔 창에 복사하여 붙여 넣기 ) 관심있는 요소의 이벤트 유형과 jquery 선택기를 지정해야합니다.

예를 들어, 언급 한 이벤트 핸들러를 신속하게 찾을 수 있습니다.

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

이것이 반환되는 것입니다 :

  • element
    이벤트 핸들러가 등록 된 실제 요소
  • events
    우리가 관심있는 이벤트 유형에 대한 jquery 이벤트 핸들러에 대한 정보가 포함 된 배열 (예 : 클릭, 변경 등)
    • 처리기
      마우스 오른쪽 단추로 클릭하고 함수 정의 표시를 선택하여 볼 수있는 실제 이벤트 처리기 방법
    • 선택기
      위임 된 이벤트에 제공되는 선택기. 직접 이벤트의 경우 비어 있습니다.
    • targets
      이 이벤트 핸들러가 대상으로하는 요소와 함께 나열하십시오. 예를 들어, 문서 객체에 등록되고 페이지의 모든 버튼을 대상으로하는 위임 된 이벤트 핸들러의 경우이 속성은 페이지의 모든 버튼을 나열합니다. 마우스를 가져 가서 크롬으로 강조 표시된 것을 볼 수 있습니다.

여기서 시도해 볼 수 있습니다


나는 이 목적을 위해 이벤트 버그 플러그인을 사용하여 파이어 버그를 사용 합니다.


@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 자체를 사용하여 설정된 이벤트 만 반환 할 수 있습니다.


1.9부터 Migrate 플러그인을 사용하여 이전 동작을 복원하는 것 외에는 이벤트를 검색하는 문서화 된 방법이 없습니다. jps에서 언급했듯이 _.data () 메소드를 사용할 수 있지만 내부 메소드입니다. 이 기능이 필요한 경우 올바른 작업을 수행하고 마이그레이션 플러그인을 사용하십시오.

의 jQuery 문서에서 .data("events")

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>

그리고 그 이미지에는 클릭 이벤트 핸들러가 첨부되어 있습니다.

imageNode.click(function () { ... });

클릭 할 수있는 영역을 전체 행으로 확장하는 것이 목적이므로 먼저 모든 이미지와 상대 행을 얻었습니다.

tableNode.find("img.folder").each(function () {
  var tr;

  tr = $(this).closest("tr");
  // <-- actual answer
});

이제 실제 anwer 줄에서 다음과 같이 방금 원래 질문에 대한 답변을 제공했습니다.

tr.click(this.onclick);

그래서 DOM 요소에서 직접 이벤트 핸들러를 가져 와서 jQuery 클릭 이벤트 핸들러에 넣었습니다. 매력처럼 작동합니다.

이제 일반적인 경우입니다. 이전 jQuery 이전에는 Douglas Crockford 가 우리에게 필적할만한 두 가지 간단하지만 강력한 기능을 사용하여 모든 이벤트를 객체에 첨부 할 수있었습니다 .

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(elem).data('events');

또는 jQuery 1.8 이상 :

jQuery._data(elem, 'events');

참고 : 다음을 사용하여 범위 $('selector').live('event', handler)지정된 이벤트를 검색 할 수 있습니다.

jQuery(document).data('events')

크롬을 사용하는 경우 jquery 디버거 플러그인을 사용해보십시오 : https://chrome.google.com/webstore/detail/jquery-debugger/dbhhnnnpaeobfddmlalhnehgclcmjimi?hl=ko


다른 방법은 jQuery를 사용하여 요소를 가져온 다음 실제 Javascript를 통해 이벤트 핸들러를 가져 와서 설정하고 재생하는 것입니다. 예를 들어 :

var oldEventHandler = $('#element')[0].onclick;
// Remove event handler
$('#element')[0].onclick = null;
// Switch it back
$('#element')[0].onclick = oldEventHandler;

위의 답변 중 일부를 결합하고 주어진 요소에서 대부분의 이벤트 리스너를 희망적으로 나열하는이 미친 듯하지만 기능적인 스크립트를 만들었습니다. 여기에서 자유롭게 최적화하십시오.

var element = $("#some-element");

// sample event handlers
element.on("mouseover", function () {
  alert("foo");
});

$(".parent-element").on("mousedown", "span", function () {
  alert("bar");
});

$(document).on("click", "span", function () {
  alert("xyz");
});

var collection = element.parents()
  .add(element)
  .add($(document));
collection.each(function() {
  var currentEl = $(this) ? $(this) : $(document);
  var tagName = $(this)[0].tagName ? $(this)[0].tagName : "DOCUMENT";
  var events = $._data($(this)[0], "events");
  var isItself = $(this)[0] === element[0]
  if (!events) return;
  $.each(events, function(i, event) {
    if (!event) return;
    $.each(event, function(j, h) {
      var found = false;        
      if (h.selector && h.selector.length > 0) {
        currentEl.find(h.selector).each(function () {
          if ($(this)[0] === element[0]) {
            found = true;
          }
        });
      } else if (!h.selector && isItself) {
        found = true;
      }

      if (found) {
        console.log("################ " + tagName);
        console.log("event: " + i);
        console.log("selector: '" + h.selector + "'");
        console.log(h.handler);
      }
    });
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="parent-element">
  <span id="some-element"></span>
</div>

참고 URL : https://stackoverflow.com/questions/2518421/jquery-find-events-handlers-registered-with-an-object



반응형