Sta*_*ano 68 javascript testing addeventlistener dom-events
这是我的问题:是否有可能以某种方式检查动态附加事件监听器的存在?或者我如何检查DOM中"onclick"(?)属性的状态?我已经像StackOverflow一样搜索了互联网,但是没有运气.这是我的HTML:
<a id="link1" onclick="linkclick(event)"> link 1 </a>
<a id="link2"> link 2 </a> <!-- without inline onclick handler -->
Run Code Online (Sandbox Code Playgroud)
然后在javascript中我将动态创建的事件监听器附加到第二个链接:
document.getElementById('link2').addEventListener('click', linkclick, false);
Run Code Online (Sandbox Code Playgroud)
代码运行良好,但我检测连接的侦听器的所有尝试都失败了:
// 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?
Run Code Online (Sandbox Code Playgroud)
jsFiddle就在这里.如果单击"添加onclick for 2"然后单击"[link 2]",则事件会激活,但"测试链接2"始终报告为false.有人可以帮忙吗?
Iva*_*van 36
无法检查是否存在动态连接的事件侦听器.
您可以看到附加事件侦听器的唯一方法是附加事件侦听器,如下所示:
elem.onclick = function () { console.log (1) }
Run Code Online (Sandbox Code Playgroud)
然后,您可以onclick
通过返回!!elem.onclick
(或类似的东西)来测试是否附加了事件侦听器.
小智 21
我做了类似的事情:
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');
});
}
Run Code Online (Sandbox Code Playgroud)
在附加侦听器时为元素创建特殊属性,然后检查它是否存在.
Ces*_*sar 18
我要做的是在函数外部创建一个布尔值为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);
}
}
Run Code Online (Sandbox Code Playgroud)
aru*_*ian 12
可能的重复:检查元素上是否有事件侦听器。没有 jQuery 请在那里找到我的答案。
基本上这里是 Chromium (Chrome) 浏览器的技巧:
getEventListeners(document.querySelector('your-element-selector'));
Run Code Online (Sandbox Code Playgroud)
这种方法不存在似乎很奇怪。最后是时候添加它了吗?
如果你愿意,你可以像下面这样:
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;
};
Run Code Online (Sandbox Code Playgroud)
tl; dr:否,您不能以任何本机支持的方式执行此操作。
我知道实现此目标的唯一方法是创建一个自定义存储对象,在其中保存添加的侦听器的记录。遵循以下内容:
/* Create a storage object. */
var CustomEventStorage = [];
Run Code Online (Sandbox Code Playgroud)
步骤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;
}
Run Code Online (Sandbox Code Playgroud)
步骤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);
}
Run Code Online (Sandbox Code Playgroud)
步骤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;
}
Run Code Online (Sandbox Code Playgroud)
步骤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);
}
Run Code Online (Sandbox Code Playgroud)
片段:
/* Create a storage object. */
var CustomEventStorage = [];
Run Code Online (Sandbox Code Playgroud)
/* 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;
}
Run Code Online (Sandbox Code Playgroud)
尽管自OP发布该问题以来已经过去了5年多,但我相信将来迷失于此问题的人们将从该答案中受益,因此随时可以提出建议或对其进行改进。
例如,您可以使用Chrome检查器手动检查EventListener是否存在.在"元素"选项卡中,您可以使用传统的"样式"子选项卡,并在其旁边显示另一个:"事件监听器".这将为您提供所有EventListener及其链接元素的列表.
2022 年更新:
我根据这个答案在 TypeScript 中编写了实用方法来附加和分离事件,但这是一个更正的答案。希望有人觉得它有帮助。
export const attachEvent = (
element: Element,
eventName: string,
callback: () => void
) => {
if (element && eventName && element.getAttribute('listener') !== 'true') {
element.setAttribute('listener', 'true');
element.addEventListener(eventName, () => {
callback();
});
}
};
export const detachEvent = (
element: Element,
eventName: string,
callback: () => void
) => {
if (eventName && element) {
element.removeEventListener(eventName, callback);
}
};
Run Code Online (Sandbox Code Playgroud)
导入它并像这样在任何地方使用它
attachEvent(domElement, 'click', this.myfunction.bind(this));
detachEvent(domElement, 'click', this.myfunction);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
126331 次 |
最近记录: |