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


当前回答

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

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

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

其他回答

我是这样做的:

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

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

我写了3个函数来做这个:

var addEvent = function(object, type, callback)
{
    if (object != null && typeof(object) != 'undefined' && object.addEventListener)
    {
        object.isAttached = typeof object.isAttached == "undefined" ? [] : object.isAttached;
        if (!object.isAttached[type])
        {
            object.isAttached[type] = true;
            object.addEventListener(type, callback, false);
        }
    }
};

var removeEvent = function(object, type, callback)
{
    if (object != null && typeof(object) != "undefined" && typeof object.isAttached != "undefined" && object.isAttached[type])
    {
        object.removeEventListener(type, callback, false);
        object.isAttached[type] = false;
    }
};

var hasEvent = function(object, type, callback)
{
    return object != null && typeof(object) != "undefined" && typeof object.isAttached != "undefined" && object.isAttached[type];
};

函数的使用很简单:

function mousemove(e)
{
    console.log("x:" + e.clientX + ", y:" + e.clientY);
}

if (hasEvent(window, "mousemove", mousemove))
    console.log('window has "mousemove" event with "mousemove" callback');
else
    console.log('window does not have "mousemove" event with "mousemove" callback');

addEvent(window, "mousemove", mousemove);

if (hasEvent(window, "mousemove", mousemove))
    console.log('window has "mousemove" event with "mousemove" callback');
else
    console.log('window does not have "mousemove" event with "mousemove" callback');
/*
Output
window does not have "mousemove" event with "mousemove"
window has "mousemove" event with "mousemove" callback
The x and y coordinates of mouse as you move it
*/

像这样的东西应该有助于文档:

var listeners = window.getEventListeners(document);
Object.keys(listeners).forEach(event => {
    console.log(event, listeners[event]);
});

或者使用选择器:

getAllEventListeners = function(el) {
 var allListeners = {}, listeners;

 while(el) {
  listeners = getEventListeners(el);

  for(event in listeners) {
   allListeners[event] = allListeners[event] || [];
   allListeners[event].push({listener: listeners[event], element: el});  
  }

  el = el.parentNode;
 }

 return allListeners;
}

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

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

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;
};
var listenerPaste = pasteAreaElm.hasOwnProperty('listenerPaste');
if (!listenerPaste) {
    pasteAreaElm.addEventListener("paste", onPasteEvent, false);
    pasteAreaElm.listenerPaste = true;
}