Reputation: 69
<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. There are many ways to find elements that have HTML event attributes like #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">
. 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.
EDIT: querySelectorAll() now selects the test3 class instead of test3 tag
Upvotes: 1
Views: 3333
Reputation: 29511
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.
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.
e.g.
document.querySelectorAll('[data-eventlisteners]')
will reveal which elements on the page have EventListeners
attached
document.querySelectorAll('[data-eventlisteners*=","]')
will reveal which elements on the page have more than one EventListener
attached
document.querySelectorAll('[data-eventlisteners*="mouseover:"]')
will reveal which elements on the page have a mouseover
EventListener
attached
document.querySelectorAll('[data-eventlisteners*="click:"][data-eventlisteners*="mouseout:"]')
will reveal which elements on the page have both a click
and a mouseout
EventListener
attached
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()
.div2
reveals itself as having two EventListeners
which listen for mouseover
and mouseout
, which, respectively, fire the functions mouseoverMe()
and mouseoutMe()
N.B. I've modified the script above quite a lot but it was originally inspired by:
Upvotes: 1
Reputation: 8064
There is no native javascript api that allows you to find event listeners that were added using 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.
Javascript offers no api for doing so, because dom elements can be removed while event listeners still referencing them.
If you want to keep track of event listeners attached to dom elements you have to do that yourself.
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.
Upvotes: 2
Reputation: 2721
There is no way, to do so directly with 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;
Upvotes: 0