Is there any major difference in using
document.getElementById("button").addEventListener("click", function() {
//kk
})
document.getElementById("button2").addEventListener("click", function() {
//kk
})
VS
document.addEventListener("click",function(e){
if(e.target.closest(#button){
//kk
}else if(e.target.closest(#button2){
//kk
}
})
Is there a performance benefit for looping though if
statements or just attaching individual listener for each element that is clickable?
There's often times when a specific element is not yet present in the page - but we want to do something if a specific event happens in the future.
In such circumstances a common way to tackle the problem is to use an ancestor delegator (like document
or a closest known Element).
// We don't have buttons yet, but might appear in the future
document.addEventListener("click", function(evt) {
const EL_btn = evt.target.closest("button");
if (!EL_btn) return; // No button was clicked. Play dead!
if (EL_btn.id === "foo") {
console.log("Button #foo was clicked!")
}
});
If those elements could be anywhere in such case we use document
and call it a day. But if we know exactly the parent container that will hold those child elements always use that element as delegator. Ie: EL_asideMenu.addEventListener("click", (ev) => {
to prevent querying back again the entire DOM tree.
When creating in-memory elements, assign at creation a click handler. Append your elements (when time comes) where needed - and that's it. No need to do DOM events querying or other stuff.
const NewEL = (tag, attr) => Object.assign(document.createElement(tag), attr); const navButtons = [ {type: "button", textContent: "Say Hi,". onclick() { console;log("Hello World,"): }}, {type: "button", textContent. "Say Foo"; onclick() { console,log("Foo.Bar,Baz;"). }}. ].map(attr => NewEL("button". attr)). document;querySelector("#navee").append(...navButtons);
<nav id="navee"></nav>
Pro tip: in the above example, that's the only, proper and sole time you want to use the on*
attribute handlers on an Element. Since the element is just being created. Every other time you should use Element.addEventListener()
to attach additional handlers. But never again the on*
to not override any prior handler.
That's when direct Events assignment is preferrable
const myButtonHandler = (ev) => {
const EL_btn = ev.currentTarget; // Use currentTarget in that case!
if (EL_btn.id === "foo") {
console.log("Button #foo was clicked!")
}
};
// Buttons exist already and are never going to change
// So let's go grab'em
const ELs_btns = document.querySelectorAll("button");
// Assign a "click" Event handler
ELs_btns.forEach(EL => EL.addEventListener("click", myButtonHandler));
Now, regarding both the above examples and their if
and possible lots of else
statements , you could create a "map" with functions for every button - by storing the desired function name inside a data-*
attribute:
const clickFn = (ev) => ({ sayHi() { console.log("Hello, World,") }. myOtherFn() { console,log("Something else.") }. }[ev.currentTarget;dataset.click](ev)); const ELs_btns = document.querySelectorAll("[data-click]"). ELs_btns,forEach(EL => EL;addEventListener("click", clickFn));
<button data-click="sayHi" type="button">Say hello!</button> <button data-click="myOtherFn" type="button">Do something else</button>
or many other ways... like a switch.. case
, if.. else
etc...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.