这是我的问题:是否可以以某种方式检查是否存在一个动态附加的事件侦听器?或者我怎么能在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]”,事件会正常启动, 但是“测试链接2”总是报告错误。 有人能帮帮我吗?


当前回答

我只是写了一个脚本来让你实现这个。它为您提供了两个全局函数:hasEvent(Node elm, String事件)和getEvents(Node elm),您可以利用它们。注意,它修改了EventTarget原型方法add/RemoveEventListener,并且不适用于通过HTML标记或elm的javascript语法添加的事件。On_event =…

更多信息在GitHub

现场演示

脚本:

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)}();

其他回答

你好,我在这里提出我的方法,它以某种方式工作,以避免在DOM的同一元素上进行多个侦听。我的方法使用JQUERY,但原理如下:

在对应用程序进行特定处理(必须在DOM元素(如click)上重新生成侦听器)之后,我们首先删除该事件以避免多次出现该事件,然后立即重新创建它。

这一原则要根据需要加以调整。这只是原理。我向你展示如何在jquery。

line 1 : $(_ELTDOM_).unbind('click');
line 2 : $(_ELTDOM_).bind('click',myFct);

我希望通过调整这个解决方案可以帮助到一些人。我坚持认为,这种解决方案不一定适用于所有情况,但它已经使解决与双、三重……相关的问题成为可能。例如,由于同一元素上的多个侦听而导致的同时处理

没有办法检查动态附加的事件侦听器是否存在。

查看事件监听器是否被附加的唯一方法是像这样附加事件监听器:

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

然后,您可以通过返回!!elem测试事件侦听器是否附加到onclick。点击(或类似的东西)。

我要做的是在你的函数外面创建一个布尔值,开始时为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);
 }
}

我是这样做的:

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');
    });
}

在附加侦听器时为元素创建一个特殊属性,然后检查它是否存在。

这种方法不存在,这似乎很奇怪。是时候加入了吗?

如果你想,你可以这样做:

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;
};