Как проверить, существует ли динамически подключенный прослушиватель событий?
Вот моя проблема: возможно ли как-то проверить наличие динамически подключенного прослушивателя событий? Или как я могу проверить состояние свойства onclick (?) В DOM? Я искал интернет, как и Qaru, для решения, но не повезло. Вот мой HTML:
<a id="link1" onclick="linkclick(event)"> link 1 </a>
<a id="link2"> link 2 </a> <!-- without inline onclick handler -->
Затем в Javascript я присоединяю динамически созданный прослушиватель событий ко 2-й ссылке:
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 this?
jsFiddle здесь.
Если вы нажмете "Добавить onclick for 2", а затем "[ссылка 2]", событие срабатывает хорошо,
но "Тестовая ссылка 2" всегда сообщает ложь.
Может кто-нибудь помочь?
Ответы
Ответ 1
Невозможно проверить, существуют ли динамически подключенные прослушиватели событий.
Единственный способ узнать, подключен ли прослушиватель событий, - это добавить прослушиватели событий следующим образом:
elem.onclick = function () { console.log (1) }
Затем вы можете проверить, подключен ли прослушиватель событий к onclick
, возвращая !!elem.onclick
(или что-то подобное).
Ответ 2
Что бы я сделал, так это создать логическое значение вне вашей функции, которое начинается с 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);
}
}
Ответ 3
Я сделал что-то вроде этого:
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');
});
}
Создание специального атрибута для элемента при подключении слушателя, а затем проверки его наличия.
Ответ 4
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);
}
Отрывок:
window.onload = function () {
var
/* Cache the test element. */
element = document.getElementById("test"),
/* Create an event listener. */
listener = function (e) {
console.log(e.type + "triggered!");
};
/* Insert the listener to the element. */
insertListener(element, "mouseover", listener);
/* Log whether the listener exists. */
console.log(listenerExists(element, "mouseover", listener));
/* Remove the listener from the element. */
removeListener(element, "mouseover", listener);
/* Log whether the listener exists. */
console.log(listenerExists(element, "mouseover", listener));
};
<!-- Include the Custom Event Storage file -->
<script src = "https://cdn.rawgit.com/angelpolitis/custom-event-storage/master/main.js"></script>
<!-- A Test HTML element -->
<div id = "test" style = "background:#000; height:50px; width: 50px"></div>
Ответ 5
Вы всегда можете проверить вручную, если ваш EventListener существует, например, с помощью инспектора Chrome.
На вкладке Элемент у вас есть традиционная подкладка "Стили", а рядом с ней - "Слушатели событий".
Это даст вам список всех EventListeners со связанными элементами.
Ответ 6
Здесь a script я использовал для проверки наличия динамически подключенного прослушивателя событий. Я использовал jQuery для присоединения обработчика события к элементу, а затем инициировал это событие (в данном случае событие 'click'). Таким образом, я могу получить и захватить свойства событий, которые будут существовать только при подключении обработчика событий.
var eventHandlerType;
$('#contentDiv').on('click', clickEventHandler).triggerHandler('click');
function clickEventHandler(e) {
eventHandlerType = e.type;
}
if (eventHandlerType === 'click') {
console.log('EventHandler "click" has been applied');
}
Ответ 7
Возможный дубликат: Проверьте, есть ли у элемента прослушиватель событий. нет JQuery.
Пожалуйста, найдите мой ответ там.
Вот трюк для браузера Chromium (Chrome):
getEventListeners(document.querySelector('your-element-selector'));
Ответ 8
Я только что написал script, который позволяет вам это сделать. Он дает вам две глобальные функции: hasEvent(Node elm, String event)
и getEvents(Node elm)
, которые вы можете использовать. Имейте в виду, что он изменяет метод прототипа EventTarget
add/RemoveEventListener
и не работает для событий, добавленных через разметку HTML или синтаксис javascript elm.on_event = ...
Дополнительная информация в GitHub
Live Demo
Script:
var hasEvent,getEvents;!function(){function b(a,b,c){c?a.dataset.events+=","+b:a.dataset.events=a.dataset.events.replace(new RegExp(b),"")}function c(a,c){var d=EventTarget.prototype[a+"EventListener"];return function(a,e,f,g,h){this.dataset.events||(this.dataset.events="");var i=hasEvent(this,a);return c&&i||!c&&!i?(h&&h(),!1):(d.call(this,a,e,f),b(this,a,c),g&&g(),!0)}}hasEvent=function(a,b){var c=a.dataset.events;return c?new RegExp(b).test(c):!1},getEvents=function(a){return a.dataset.events.replace(/(^,+)|(,+$)/g,"").split(",").filter(function(a){return""!==a})},EventTarget.prototype.addEventListener=c("add",!0),EventTarget.prototype.removeEventListener=c("remove",!1)}();
Ответ 9
Похоже, что не существует кросс-браузерная функция, которая ищет события, зарегистрированные в данном элементе.
Тем не менее, можно просматривать функции обратного вызова для элементов в некоторых браузерах, используя их инструменты разработки. Это может быть полезно при попытке определить, как функционирует веб-страница, или для отладки кода.
Firefox
Сначала просмотрите элемент на вкладке "Инспектор" в инструментах разработчика. Это можно сделать:
- На странице, щелкнув правой кнопкой мыши элемент на веб-странице, который вы хотите проверить, и выбрав в меню "Проверить элемент".
- Внутри консоли используйте функцию для выбора элемента, например document.querySelector, а затем щелкните значок рядом с элементом, чтобы просмотреть его на вкладке "Инспектор".
Если какие-либо события были зарегистрированы в элементе, вы увидите кнопку, содержащую слово Event рядом с элементом. Нажав на нее, вы увидите события, которые были зарегистрированы с помощью элемента. Нажав на стрелку рядом с событием, вы можете просмотреть функцию обратного вызова для него.
Chrome
Сначала просмотрите элемент на вкладке "Элементы" в инструментах разработчика. Это можно сделать:
- На странице, щелкнув правой кнопкой мыши на элементе на веб-странице, который вы хотите проверить, и выбрав "Проверить" в меню
- Внутри консоли с помощью функции для выбора элемента, например document.querySelector, щелкните правой кнопкой мыши элемент и выберите "Показать в панели элементов", чтобы просмотреть его на вкладке "Инспектор".
Рядом с разделом окна, в котором отображается дерево, содержащее элементы веб-страницы, должен быть еще один раздел с вкладкой, озаглавленной "Прослушиватели событий". Выберите его, чтобы увидеть события, которые были зарегистрированы для элемента. Чтобы просмотреть код для данного события, нажмите ссылку справа от него.
В Chrome события для элемента также можно найти с помощью функции getEventListeners. Однако, основываясь на моих тестах, функция getEventListeners не перечисляет события, когда ей передается несколько элементов. Если вы хотите найти все элементы на странице, которые имеют прослушиватели, и просмотреть функции обратного вызова для этих прослушивателей, вы можете использовать следующий код в консоли для этого:
var elems = document.querySelectorAll('*');
for (var i=0; i <= elems.length; i++) {
var listeners = getEventListeners(elems[i]);
if (Object.keys(listeners).length < 1) {
continue;
}
console.log(elems[i]);
for (var j in listeners) {
console.log('Event: '+j);
for (var k=0; k < listeners[j].length; k++) {
console.log(listeners[j][k].listener);
}
}
}
Пожалуйста, измените этот ответ, если вы знаете способы сделать это в указанных браузерах или в других браузерах.
Ответ 10
Если я хорошо понимаю, вы можете только проверить, проверен ли слушатель, а не какой конкретно слушатель является докладчиком.
Так что некоторый специальный код заполнит пробел для обработки вашего потока кодирования. Практическим методом было бы создать state
с использованием переменных. Например, подключите средство проверки прослушивателя следующим образом:
var listenerPresent=false
затем, если вы установите слушателя, просто измените значение:
listenerPresent=true
затем внутри вашего обратного вызова eventListener вы можете назначить определенные функции внутри и таким же образом распределить доступ к функциям в зависимости от некоторого состояния в качестве переменной, например:
accessFirstFunctionality=false
accessSecondFunctionality=true
accessThirdFunctionality=true
Ответ 11
Просто удалите событие перед его добавлением:
document.getElementById('link2').removeEventListener('click', linkclick, false);
document.getElementById('link2').addEventListener('click', linkclick, false);
Ответ 12
Я только что узнал об этом, пытаясь узнать, связано ли мое событие....
если вы выполните:
item.onclick
он вернет "null"
но если вы выполните:
item.hasOwnProperty('onclick')
то это "TRUE"
поэтому я думаю, что когда вы используете addEventListener для добавления обработчиков событий, единственный доступ к нему - через "hasOwnProperty". Хотелось бы, чтобы я знал, почему или как, но, увы, после исследования я не нашел объяснений.
Ответ 13
Теоретически вы можете добавить addEventListener и removeEventListener, чтобы добавить флаг удаления к объекту this. Гадкий, и я не проверял...