I want a specific EventListener I add to an EventTarget to be executed last (but before the default action) independently of the order they were registered in, with the additional constraint that the event is not cancelable, meaning it can only be triggered once to achieve this purpose.
I already tried using .addEventListener within an event listener, but this only registers an EventListener to be executed for the next time the event occurs, not during the current handling. Unfortunately EventListenerList never became part of the DOM spec, meaning it's also not an option to use .stopImmediatePropagation and execute the other events manually before executing the actions to be done last.
I am not looking for the order in which they are executed, I am aware modern browser engines execute EventListeners in the order of registration. I am asking about ways to bypass that behavior (may it be in result only).
The specific need for this is in a content script (meaning I have no control over the other EventListeners added (or the order in which that happens)) that rewrites URLs right before they are used - however some pages have EventListeners that do their own rewriting during the same event.
An example of the current behavior:
// The content script:
document.getElementById("target").addEventListener("click",last);
function last() {
this.innerHTML="Correct!";
console.log("This is supposed to occur last.")
}
// The webpage:
document.getElementById("target").addEventListener("click",first);
function first() {
this.innerHTML="Incorrect!";
console.log("This is supposed to occur first.")
}
<button id="target">
Click me!
</button>
I want a specific EventListener I add to an EventTarget to be executed last (but before the default action) independently of the order they were registered in, with the additional constraint that the event is not cancelable, meaning it can only be triggered once to achieve this purpose.
I already tried using .addEventListener within an event listener, but this only registers an EventListener to be executed for the next time the event occurs, not during the current handling. Unfortunately EventListenerList never became part of the DOM spec, meaning it's also not an option to use .stopImmediatePropagation and execute the other events manually before executing the actions to be done last.
I am not looking for the order in which they are executed, I am aware modern browser engines execute EventListeners in the order of registration. I am asking about ways to bypass that behavior (may it be in result only).
The specific need for this is in a content script (meaning I have no control over the other EventListeners added (or the order in which that happens)) that rewrites URLs right before they are used - however some pages have EventListeners that do their own rewriting during the same event.
An example of the current behavior:
// The content script:
document.getElementById("target").addEventListener("click",last);
function last() {
this.innerHTML="Correct!";
console.log("This is supposed to occur last.")
}
// The webpage:
document.getElementById("target").addEventListener("click",first);
function first() {
this.innerHTML="Incorrect!";
console.log("This is supposed to occur first.")
}
<button id="target">
Click me!
</button>
Share
Improve this question
edited Feb 28, 2019 at 19:49
asked Dec 17, 2017 at 23:26
user3532811user3532811
4
- Please provide code – Dexygen Commented Dec 17, 2017 at 23:43
- 2 Possible duplicate of The Order of Multiple Event Listeners – Reactgular Commented Dec 17, 2017 at 23:47
- not sure if I understand, but maybe you can handle the URLs change event instead of the click event – Slai Commented Dec 18, 2017 at 1:22
- That is not a possibility, since the URL is changed in the click event, and observing this change is only possible outside of that click event, when the default action has already fired. – user3532811 Commented Dec 18, 2017 at 1:41
2 Answers
Reset to default 3A simple but by no means pletely sound way to achieve this is to wrap the event you want to occur last in a setTimeout(). This will create a delay in its execution. Of course if there are other functions that are asynchronous within the other event listeners it is possible you will not be able to fully predict the needed delay:
function last() {
setTimeout( () => {
this.innerHTML=("Correct!");
console.log("This is supposed to occur last.")
})
}
// The webpage:
document.getElementById("target").addEventListener("click",last);
document.getElementById("target").addEventListener("click",first);
function first() {
this.innerHTML="Incorrect!";
console.log("This is supposed to occur first.")
}
<button id="target">
Click me!
</button>
Alternative might be to handle all click events and check if the event.target
is element to handle:
function first() { console.log('first') }
function second() { console.log('second') }
function last(e) { if (e.target.id === 'target') console.log('last') }
target.addEventListener("click", first);
document.body.addEventListener("click", last);
target.addEventListener("click", second);
<button id="target">
Click me!
</button>
Because of the event bubbling, the button events are executed before its parent(s) events.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745033793a4607394.html
评论列表(0条)