[javascript] 동적으로 연결된 이벤트 리스너가 있는지 여부를 확인하는 방법은 무엇입니까?

내 문제는 다음과 같습니다. 어떻게 든 동적으로 연결된 이벤트 리스너의 존재를 확인할 수 있습니까? 또는 DOM에서 “onclick”(?) 속성의 상태를 어떻게 확인할 수 있습니까? 해결책을 찾기 위해 Stack Overflow와 마찬가지로 인터넷을 검색했지만 운이 없습니다. 내 HTML은 다음과 같습니다.

<a id="link1" onclick="linkclick(event)"> link 1 </a>
<a id="link2"> link 2 </a> <!-- without inline onclick handler -->

그런 다음 Javascript에서 동적으로 생성 된 이벤트 리스너를 두 번째 링크에 연결합니다.

document.getElementById('link2').addEventListener('click', linkclick, false);

코드는 잘 실행되지만 연결된 리스너를 감지하려는 모든 시도는 실패합니다.

// test for #link2 - dynamically created eventlistener
alert(elem.onclick); // null
alert(elem.hasAttribute('onclick')); // false
alert(elem.click); // function click(){[native code]} // btw, what's this?

jsFiddle이 여기 있습니다 . “Add onclick for 2″를 클릭 한 다음 “[link 2]”를 클릭하면 이벤트가 제대로 실행되지만 “Test link 2″는 항상 false를보고합니다. 누군가 도울 수 있습니까?



답변

동적으로 연결된 이벤트 리스너가 있는지 여부를 확인할 수있는 방법이 없습니다.

이벤트 리스너가 연결되었는지 확인할 수있는 유일한 방법은 다음과 같이 이벤트 리스너를 연결하는 것입니다.

elem.onclick = function () { console.log (1) }

그런 다음 onclick반환 !!elem.onclick(또는 유사한 항목) 을 통해 이벤트 리스너가 연결되었는지 테스트 할 수 있습니다 .


답변

나는 다음과 같이했다.

const element = document.getElementById('div');

if (element.getAttribute('listener') !== 'true') {
     element.addEventListener('click', function (e) {
         const elementClicked = e.target;
         elementClicked.setAttribute('listener', 'true');
         console.log('event has been attached');
    });
}

리스너가 첨부 될 때 요소에 대한 특수 속성을 생성 한 다음 존재하는지 확인합니다.


답변

내가 할 일은 FALSE로 시작하고 이벤트를 연결할 때 TRUE로 설정되는 함수 외부에 부울을 만드는 것입니다. 이것은 이벤트를 다시 첨부하기 전에 일종의 플래그 역할을합니다. 여기에 아이디어의 예가 있습니다.

// initial load
var attached = false;

// this will only execute code once
doSomething = function()
{
 if (!attached)
 {
  attached = true;
  //code
 }
}

//attach your function with change event
window.onload = function()
{
 var txtbox = document.getElementById('textboxID');

 if (window.addEventListener)
 {
  txtbox.addEventListener('change', doSomething, false);
 }
 else if(window.attachEvent)
 {
  txtbox.attachEvent('onchange', doSomething);
 }
}


답변

중복 가능성 : 요소에 이벤트 리스너가 있는지 확인합니다. jQuery 없음
거기에서 내 대답을 찾으십시오.

기본적으로 Chromium (Chrome) 브라우저의 트릭은 다음과 같습니다.

getEventListeners(document.querySelector('your-element-selector'));


답변

tl; dr : 아니요, 기본적으로 지원되는 방식으로는이 작업을 수행 할 수 없습니다.


이를 달성하기 위해 내가 아는 유일한 방법은 추가 된 리스너의 기록을 보관하는 사용자 지정 스토리지 객체를 만드는 것입니다. 다음과 같은 내용 :

/* Create a storage object. */
var CustomEventStorage = [];

1 단계 : 먼저 저장소 개체를 탐색하고 요소가 지정된 요소 (또는 false)의 레코드를 반환 할 수있는 함수가 필요합니다.

/* The function that finds a record in the storage by a given element. */
function findRecordByElement (element) {
    /* Iterate over every entry in the storage object. */
    for (var index = 0, length = CustomEventStorage.length; index < length; index++) {
        /* Cache the record. */
        var record = CustomEventStorage[index];

        /* Check whether the given element exists. */
        if (element == record.element) {
            /* Return the record. */
            return record;
        }
    }

    /* Return false by default. */
    return false;
}

2 단계 : 그런 다음 이벤트 리스너를 추가하고 리스너를 스토리지 객체에 삽입 할 수있는 함수가 필요합니다.

/* The function that adds an event listener, while storing it in the storage object. */
function insertListener (element, event, listener, options) {
    /* Use the element given to retrieve the record. */
    var record = findRecordByElement(element);

    /* Check whether any record was found. */
    if (record) {
        /* Normalise the event of the listeners object, in case it doesn't exist. */
        record.listeners[event] = record.listeners[event] || [];
    }
    else {
        /* Create an object to insert into the storage object. */
        record = {
            element: element,
            listeners: {}
        };

        /* Create an array for event in the record. */
        record.listeners[event] = [];

        /* Insert the record in the storage. */
        CustomEventStorage.push(record);
    }

    /* Insert the listener to the event array. */
    record.listeners[event].push(listener);

    /* Add the event listener to the element. */
    element.addEventListener(event, listener, options);
}

3 단계 : 질문의 실제 요구 사항과 관련하여 지정된 이벤트에 대한 이벤트 리스너에 요소가 추가되었는지 확인하려면 다음 함수가 필요합니다.

/* The function that checks whether an event listener is set for a given event. */
function listenerExists (element, event, listener) {
    /* Use the element given to retrieve the record. */
    var record = findRecordByElement(element);

    /* Check whether a record was found & if an event array exists for the given event. */
    if (record && event in record.listeners) {
        /* Return whether the given listener exists. */
        return !!~record.listeners[event].indexOf(listener);
    }

    /* Return false by default. */
    return false;
}

4 단계 : 마지막으로 스토리지 객체에서 리스너를 삭제할 수있는 함수가 필요합니다.

/* The function that removes a listener from a given element & its storage record. */
function removeListener (element, event, listener, options) {
    /* Use the element given to retrieve the record. */
    var record = findRecordByElement(element);

    /* Check whether any record was found and, if found, whether the event exists. */
    if (record && event in record.listeners) {
        /* Cache the index of the listener inside the event array. */
        var index = record.listeners[event].indexOf(listener);

        /* Check whether listener is not -1. */
        if (~index) {
            /* Delete the listener from the event array. */
            record.listeners[event].splice(index, 1);
        }

        /* Check whether the event array is empty or not. */
        if (!record.listeners[event].length) {
            /* Delete the event array. */
            delete record.listeners[event];
        }
    }

    /* Add the event listener to the element. */
    element.removeEventListener(event, listener, options);
}

단편:


OP가 질문을 게시 한 지 5 년 이상이 지났지 만 앞으로 우연히 발견 한 사람들이이 답변을 통해 도움이 될 것이라고 생각하므로 자유롭게 제안하거나 개선하십시오. 😊


답변

예를 들어 Chrome 검사기를 사용하여 EventListener가 존재하는지 항상 수동으로 확인할 수 있습니다. 요소 탭에는 기존의 “스타일”하위 탭이 있으며 그 옆에는 “이벤트 리스너”라는 하위 탭이 있습니다. 링크 된 요소와 함께 모든 EventListener 목록을 제공합니다.


답변

이 방법이 존재하지 않는 것이 이상해 보입니다. 드디어 추가 할 때인가?

원한다면 다음과 같이 할 수 있습니다.

var _addEventListener = EventTarget.prototype.addEventListener;
var _removeEventListener = EventTarget.prototype.removeEventListener;
EventTarget.prototype.events = {};
EventTarget.prototype.addEventListener = function(name, listener, etc) {
  var events = EventTarget.prototype.events;
  if (events[name] == null) {
    events[name] = [];
  }

  if (events[name].indexOf(listener) == -1) {
    events[name].push(listener);
  }

  _addEventListener(name, listener);
};
EventTarget.prototype.removeEventListener = function(name, listener) {
  var events = EventTarget.prototype.events;

  if (events[name] != null && events[name].indexOf(listener) != -1) {
    events[name].splice(events[name].indexOf(listener), 1);
  }

  _removeEventListener(name, listener);
};
EventTarget.prototype.hasEventListener = function(name) {
  var events = EventTarget.prototype.events;
  if (events[name] == null) {
    return false;
  }

  return events[name].length;
};