Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/426.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何检查动态附加的事件侦听器是否存在?_Javascript_Testing_Addeventlistener_Dom Events - Fatal编程技术网

Javascript 如何检查动态附加的事件侦听器是否存在?

Javascript 如何检查动态附加的事件侦听器是否存在?,javascript,testing,addeventlistener,dom-events,Javascript,Testing,Addeventlistener,Dom Events,我的问题是:是否有可能检查动态附加的事件侦听器的存在?或者如何检查DOM中“onclick”(?)属性的状态?我在互联网上搜索了一个解决方案,就像堆栈溢出一样,但没有运气。这是我的html: 。 如果单击“为2添加onclick”,然后单击“[link 2]”,事件将正常触发, 但是“测试链接2”总是报告错误。 有人能帮忙吗?无法检查是否存在动态附加的事件侦听器 查看事件侦听器是否已连接的唯一方法是通过以下方式连接事件侦听器: elem.onclick = function () { conso

我的问题是:是否有可能检查动态附加的事件侦听器的存在?或者如何检查DOM中“onclick”(?)属性的状态?我在互联网上搜索了一个解决方案,就像堆栈溢出一样,但没有运气。这是我的html:

。
如果单击“为2添加onclick”,然后单击“[link 2]”,事件将正常触发,
但是“测试链接2”总是报告错误。

有人能帮忙吗?

无法检查是否存在动态附加的事件侦听器

查看事件侦听器是否已连接的唯一方法是通过以下方式连接事件侦听器:

elem.onclick = function () { console.log (1) }
let element = document.getElementsById("someElement");

if(!element.classList.contains('attached-listener'))
   element.addEventListener("click", this.itemClicked);

element.classList.add('attached-listener');
if (el.getAttribute('data-has_click_handler'))
    console.log('yep, this element has a click handler');

然后,您可以通过返回
!!来测试事件侦听器是否连接到
onclick
!!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);
 }
}

下面是一个脚本,我用来检查是否存在动态附加的事件侦听器。我使用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');
}

我只是想看看我的活动是否有附件,才发现这一点

如果您这样做:

item.onclick
它将返回“null”

但如果你这样做了:

item.hasOwnProperty('onclick')
那么这是“真的”


因此,我认为当您使用“addEventListener”添加事件处理程序时,访问它的唯一方法是通过“hasOwnProperty”。我希望我知道为什么或者怎么做,但遗憾的是,在研究之后,我还没有找到一个解释。

我只是写了一个脚本,让你实现这一点。它提供了两个全局函数:
hasEvent(Node-elm,String-event)
getEvents(Node-elm)
,您可以使用它们。请注意,它修改了
EventTarget
prototype方法
add/RemoveEventListener
,并且不适用于通过HTML标记或
elm.on\u event=..的javascript语法添加的事件

脚本:

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

例如,您可以使用Chrome inspector手动检查EventListener是否存在。 在“元素”选项卡中,有传统的“样式”子选项卡,靠近它的是另一个子选项卡:“事件侦听器”。
这将为您提供所有EventListener及其链接元素的列表。

我做了如下操作:

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

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

tl;dr:不,您不能以任何本机支持的方式执行此操作


我知道实现这一点的唯一方法是创建一个自定义存储对象,在其中保存添加的侦听器的记录。大致如下:

/* Create a storage object. */
var CustomEventStorage = [];
步骤1:首先,您需要一个函数,该函数可以遍历存储对象并返回给定元素(或false)的元素记录

步骤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 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);
}
/* 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);
}

片段:

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)}();
window.onload=函数(){
变量
/*缓存测试元素*/
元素=document.getElementById(“测试”),
/*创建一个事件侦听器*/
侦听器=函数(e){
console.log(e.type+“tricked!”);
};
/*将侦听器插入元素*/
insertListener(元素“mouseover”,listener);
/*记录侦听器是否存在*/
log(listenerExists(元素“mouseover”,listener));
/*从元素中删除侦听器*/
removeListener(元素“mouseover”,listener);
/*记录侦听器是否存在*/
log(listenerExists(元素“mouseover”,listener));
};

理论上,您可以借助addEventListener和removeEventListener向“this”对象添加或删除标志。丑陋,我还没有测试…

可能重复: 请在那里找到我的答案

Chrome(Chrome)浏览器的基本技巧如下:

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

似乎没有跨浏览器功能来搜索在给定元素下注册的事件

但是,在某些浏览器中,可以使用其开发工具查看元素的回调函数。这在尝试确定网页如何工作或调试代码时非常有用

Firefox

首先,在开发人员工具的Inspector选项卡中查看元素。可以这样做:

  • 在页面上,右键单击要检查的网页项目,然后从菜单中选择“检查元素”
  • 在控制台中,使用一个函数选择元素,例如document.querySelector,然后单击元素旁边的图标以在Inspector选项卡中查看它
如果向元素注册了任何事件,您将在元素旁边看到一个包含单词Event的按钮。单击它将允许您查看已向元素注册的事件。单击事件旁边的箭头可以查看该事件的回调函数

Chrome

首先,在开发人员工具的“元素”选项卡中查看元素。可以这样做:

  • 通过右键单击网页上要检查的项目并从菜单中选择“inspect”(检查),在页面上进行检查
  • 在控制台中,使用一个功能选择元素,例如document.querySelector,右键单击元素,然后选择“在元素面板中显示”以vie
    listenerPresent=true
    
    accessFirstFunctionality=false
    accessSecondFunctionality=true
    accessThirdFunctionality=true
    
    document.getElementById('link2').removeEventListener('click', linkclick, false);
    document.getElementById('link2').addEventListener('click', linkclick, false);
    
    let element = document.getElementsById("someElement");
    
    if(!element.classList.contains('attached-listener'))
       element.addEventListener("click", this.itemClicked);
    
    element.classList.add('attached-listener');
    
    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;
    }
    
    let flagClickHandledElements = function() {
        let oldEventListener = EventTarget.prototype.addEventListener;
        EventTarget.prototype.addEventListener = function(event_name, handler_func) {
            if (event_name === 'click') {
                if (this.setAttribute) {
                    this.setAttribute('data-has_click_handler', true);
                }
            }
            if (oldEventListener)
                oldEventListener(event_name, handler_func);
        }
    }
    
    function injectScript(func) {
        let codeString = '(' + func + ')();';
        let script = document.createElement('script');
        script.textContent = codeString;
        (document.head||document.documentElement).appendChild(script);
    }
    
    injectScript(flagClickHandledElements);
    
    function onPageDoneLoading(details)
    {
        chrome.tabs.sendMessage(details.tabId, {"action": "doneloading"});
    }
    
    chrome.webNavigation.onCompleted.addListener(onPageDoneLoading);
    
    let gatherOldStyleClickHandledElements = function() {
        let all_elements = document.getElementsByTagName("*");
        for (let i = 0; i < all_elements.length; i++) {
            let el = all_elements[i];
            if (el.setAttribute && el.onclick) {
                el.setAttribute('data-has_click_handler', true);
            }
        }
    }
    
    function onReceiveMessage(request) {
        if (request.action === 'doneloading') {
            injectScript(gatherOldStyleClickHandledElements);
        } else {
            console.log('Unrecognized message');
        }
    
        return Promise.resolve("Dummy response to keep the console quiet");
    }
    
    if (el.getAttribute('data-has_click_handler'))
        console.log('yep, this element has a click handler');