[英]How to use JavaScript to find all elements which have event listeners?
<div id="test1" onlick="testFunction()" role="button" tabindex="0">A custom button</div>
<div id="test2" role="button" tabindex="0">Another custom button</div>
<button class="test3">A final button</button>
<ul id="test4">
<li>Cookies</li>
<li>Cream</li>
</ul>
<div id="test5">Just a div, not clickable </div>
document.getElementById('test2').addEventListener('keypress', function() {
console.log("foo");
}
)
document.querySelectorAll('.test3').forEach(item => {
item.addEventListener('click', event => {
console.log("bar");
})
})
document.getElementById('test4').onclick = function(event) {
let target = event.target;
if (target.tagName != 'li') {
event.target.addClass('highlight');
}
};
I'm interested in using JavaScript (preferably no jQuery or other library) to find all DOM elements which have events attached to them.我对使用 JavaScript(最好没有 jQuery 或其他库)来查找所有附加了事件的 DOM 元素很感兴趣。 There are many ways to find elements that have HTML event attributes like
#test1
.有很多方法可以找到具有 HTML 事件属性的元素,例如
#test1
。 But it is unclear how to find elements that have events added via a script like #test2
or .test3
or the <ul id="test4">
.但目前尚不清楚如何找到通过
#test2
或.test3
或<ul id="test4">
等脚本添加事件的元素。 A correct answer would return an array with four elements.正确答案将返回一个包含四个元素的数组。
An even better response would additionally find the elements using event delegation like the <li>
but it seems like that may not be possible.更好的响应会另外找到使用事件委托的元素,如
<li>
但看起来这可能是不可能的。
EDIT: querySelectorAll() now selects the test3 class instead of test3 tag编辑:querySelectorAll() 现在选择 test3 类而不是 test3 标签
There is no native javascript api that allows you to find event listeners that were added using eventTarget.addEventListener
.没有本机 javascript api 允许您查找使用
eventTarget.addEventListener
添加的事件侦听器。
You can still get events added using the onclick
attribute whether the attribute was set using javascript or inline through html - in this case u are not getting the event listener, but you are getting the value of the onclick
attribute which are two different things. You can still get events added using the
onclick
attribute whether the attribute was set using javascript or inline through html - in this case u are not getting the event listener, but you are getting the value of the onclick
attribute which are two different things.
Javascript offers no api for doing so, because dom elements can be removed while event listeners still referencing them. Javascript 不提供 api 这样做,因为可以在事件侦听器仍然引用它们时删除 dom 元素。
If you want to keep track of event listeners attached to dom elements you have to do that yourself.如果你想跟踪附加到 dom 元素的事件监听器,你必须自己做。
Apart from that chrome has getEventListeners
command line api which works with dom elements, however it is a developer tools command line api and so it only works when called from developer tools.除此之外,chrome 还有
getEventListeners
命令行 api 可与 dom 元素一起使用,但它是开发人员工具命令行 api ,因此仅在从开发人员工具调用时才有效。
There is no way, to do so directly with JavaScript.没办法,直接用JavaScript来做。
However, you can use this approach and add an attribute while binding events to the elements.但是,您可以使用这种方法并在将事件绑定到元素时添加属性。
document.getElementById('test2').addEventListener('keypress', function() { this.setAttribute("event", "yes"); console.log("foo"); } ) document.querySelectorAll('test3').forEach(item => { item.addEventListener('click', event => { this.setAttribute("event", "yes"); console.log("bar"); }) }) document.getElementById('test4').onclick = function(event) { let target = event.target; this.setAttribute("event", "yes"); if (target.tagName.= 'li') { event.target;addClass('highlight'); } };
And this is how you can find the elements having events bind to them:这就是您如何找到具有事件绑定到它们的元素的方法:
var eventElements = document.querySelectorAll("[event='yes']"); var countEventElements = eventElements.length;
You can extend EventTarget.addEventListener
so that any element to which you add an EventListener
then declares that EventListener
in an HTML5 custom data-* attribute in its own markup.您可以扩展
EventTarget.addEventListener
,这样您添加EventListener
的任何元素都可以在其自己的标记中的HTML5 自定义 data-* 属性中声明该EventListener
。
When declared, the custom attribute will look like this:声明后,自定义属性将如下所示:
data-eventlisteners="['mouseover:showButton','mouseout:fadeButton','click:animateButton']"
Once one or more elements have such custom attributes , you may query the elements via JavaScript.一旦一个或多个元素具有此类自定义属性,您就可以通过 JavaScript 查询这些元素。
eg例如
document.querySelectorAll('[data-eventlisteners]')
will reveal which elements on the page have EventListeners
attached document.querySelectorAll('[data-eventlisteners]')
将显示页面上的哪些元素附加了EventListeners
document.querySelectorAll('[data-eventlisteners*=","]')
will reveal which elements on the page have more than one EventListener
attached document.querySelectorAll('[data-eventlisteners*=","]')
将显示页面上的哪些元素附加了多个EventListener
document.querySelectorAll('[data-eventlisteners*="mouseover:"]')
will reveal which elements on the page have a mouseover
EventListener
attached document.querySelectorAll('[data-eventlisteners*="mouseover:"]')
将显示页面上的哪些元素附加了mouseover
EventListener
document.querySelectorAll('[data-eventlisteners*="click:"][data-eventlisteners*="mouseout:"]')
will reveal which elements on the page have both a click
and a mouseout
EventListener
attached document.querySelectorAll('[data-eventlisteners*="click:"][data-eventlisteners*="mouseout:"]')
将揭示页面上的哪些元素同时具有click
和mouseout
EventListener
etc.等等
Working Example:工作示例:
const declareEventListeners = () => { EventTarget.prototype._addEventListener = EventTarget.prototype.addEventListener; EventTarget.prototype.addEventListener = function(eventType, eventFunction, eventOptions) { // REINSTATE ORIGINAL FUNCTIONALITY FOR addEventListener() METHOD let _eventOptions = (eventOptions === undefined)? false: eventOptions; this._addEventListener(eventType, eventFunction, _eventOptions); // THEN, IF EVENTTARGET IS NOT WINDOW OR DOCUMENT if (this.nodeType === 1) { let eventAction = eventFunction.name || 'anonymousFunction'; let eventListenerLabel = `${eventType}:${eventAction}`; let eventListenerLabelsArray = (this.dataset.eventlisteners)? JSON.parse(this.dataset.eventlisteners.replaceAll( "'", '"')): []; eventListenerLabelsArray.push(eventListenerLabel); let eventListenerLabelsString = JSON.stringify(eventListenerLabelsArray).replaceAll('"', "'"); this.dataset.eventlisteners = eventListenerLabelsString; } } }; const clickMe = (e) => { e.target.classList.toggle('circle'); } const mouseoverMe = (e) => { e.target.style.setProperty('background-color', 'rgb(255, 127, 0)'); } const mouseoutMe = (e) => { e.target.removeAttribute('style'); } const logMarkup = () => { console.log(document.querySelector('section').innerHTML); } declareEventListeners(); document.querySelector('.div1').addEventListener('click', clickMe, false); document.querySelector('.div2').addEventListener('mouseover', mouseoverMe, false); document.querySelector('.div2').addEventListener('mouseout', mouseoutMe, false); logMarkup();
.div1, .div2 { float: left; width: 100px; height: 100px; line-height: 50px; margin-right: 12px; text-align: center; color: rgb(255, 255, 255); background-color: rgb(255, 0, 0); }.div1 { line-height: 100px; cursor: pointer; }.div1.circle { border-radius: 50%; }
<section> <div class="div1">click</div> <div class="div2">mouseover<br />mouseout</div> </section>
You'll see in the example above:您将在上面的示例中看到:
.div1
reveals itself as having a single EventListener
which listens for click
and fires the function clickMe()
.div1
显示自己有一个EventListener
,它监听click
并触发函数clickMe()
.div2
reveals itself as having two EventListeners
which listen for mouseover
and mouseout
, which, respectively, fire the functions mouseoverMe()
and mouseoutMe()
.div2
显示自己有两个EventListeners
,它们监听mouseover
和mouseout
,分别触发函数mouseoverMe()
和mouseoutMe()
NB I've modified the script above quite a lot but it was originally inspired by:注意我已经对上面的脚本进行了很多修改,但它最初的灵感来自:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.