How to addEventListener to multiple elements in a single line
Well, if you have an array with the elements you could do:
let elementsArray = document.querySelectorAll("whatever");
elementsArray.forEach(function(elem) {
elem.addEventListener("input", function() {
//this function does stuff
});
});
addEventListener with multiple elements
The best way is to have as few event listeners as possible in your code. So instead of attaching an event listener to each and every button, you can attach 1 single event listener to the area
div and make suitable changes based on event.target
attribute.
Run the below working code snippet:
document.getElementById('area').addEventListener('click', function(event) { func(event.target);});
function func(element) { element.style.backgroundColor = "blue";}
<div id="area"> <button type="button" class="btn" id="btn1">Play With Me!</button> <button type="button" class="btn" id="btn2">Play With Me!</button></div>
Adding event listeners to multiple elements
You need to have there anonymous function for that as you invoke alert()
function immediately in your example:
... .addEventListener('change', function() { alert('test!')}, false ...
For now according to your code addEventListener
tries to add result of undefined
(return of alert()
function).
Or you can just pass function handler for that:
function alertMe() {
alert( 'test!' );
}
...
... .addEventListener('change', alertMe, false ...
Note: that by making somefunction(arg[, arg...])
call you reference not to function, but to what function returns.
react how to add event listeners to multiple elements at once
React is perfect for this, because it allows you to reuse components! You could make a component that contains your click handler, then reuse it throughout your application.
const MyReusableButton = () => {
const myClickHandler = () => {
console.log("Clicked!");
}
return <button onClick = {myClickHandler}>Click Me</button>;
}
const App = () => {
// now I can reuse my button component as many times as I want!
return (
<div>
<MyReusableButton />
<MyReusableButton />
<MyReusableButton />
<MyReusableButton />
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
How to apply an eventListener to multiple elements with the same class and have each element respond independently
In the first version you are executing the pickSelection
function instead of passing its reference, the addEventListener
expects a function reference as a callback when the particular event is triggered.
But since you passed return value of the pickSelection
function which is undefined
(as you are not returning anything from the pickSelection
so by default it is returning undefined
) it is not working.
In the second version you are actually passing the function reference to the addEventListner
, which being a arrow function syntax.
This following would also work, by simply passing the reference pickSelection
, but this time it will receive the event
object.
const selection = document.querySelectorAll(".zone");selection.forEach(element => { element.addEventListener('click', pickSelection)})function pickSelection(event) { //getting the event object from the callback, target refers to the current element clicked. console.log(event.target.textContent)}
<div class='container'> <div class="zone green">lt;/div> <div class="zone red">lt;/div> <div class="zone blue">lt;/div> <div class="zone yellow">lt;/div> <div class="zone purple">lt;/div> <div class="zone brown">lt;/div> <div class="zone green">lt;/div> <div class="zone red">lt;/div> <div class="zone blue">lt;/div> <div class="zone yellow">lt;/div> <div class="zone purple">lt;/div> <div class="zone brown">lt;/div></div>
adding multiple event listeners to one element
Maybe you can use a helper function like this:
// events and args should be of type Array
function addMultipleListeners(element,events,handler,useCapture,args){
if (!(events instanceof Array)){
throw 'addMultipleListeners: '+
'please supply an array of eventstrings '+
'(like ["click","mouseover"])';
}
//create a wrapper to be able to use additional arguments
var handlerFn = function(e){
handler.apply(this, args && args instanceof Array ? args : []);
}
for (var i=0;i<events.length;i+=1){
element.addEventListener(events[i],handlerFn,useCapture);
}
}
function handler(e) {
// do things
};
// usage
addMultipleListeners(
document.getElementById('first'),
['touchstart','click'],
handler,
false);
[Edit nov. 2020] This answer is pretty old. The way I solve this nowadays is by using an actions
object where handlers are specified per event type, a data-attribute
for an element to indicate which action should be executed on it and one generic document wide handler method (so event delegation).
const firstElemHandler = (elem, evt) =>
elem.textContent = `You ${evt.type === "click" ? "clicked" : "touched"}!`;
const actions = {
click: {
firstElemHandler,
},
touchstart: {
firstElemHandler,
},
mouseover: {
firstElemHandler: elem => elem.textContent = "Now ... click me!",
outerHandling: elem => {
console.clear();
console.log(`Hi from outerHandling, handle time ${
new Date().toLocaleTimeString()}`);
},
}
};
Object.keys(actions).forEach(key => document.addEventListener(key, handle));
function handle(evt) {
const origin = evt.target.closest("[data-action]");
return origin &&
actions[evt.type] &&
actions[evt.type][origin.dataset.action] &&
actions[evt.type][origin.dataset.action](origin, evt) ||
true;
}
[data-action]:hover {
cursor: pointer;
}
<div data-action="outerHandling">
<div id="first" data-action="firstElemHandler">
<b>Hover, click or tap</b>
</div>
this is handled too (on mouse over)
</div>
Controlling Multiple Elements from a Single Event Listener
This seems to be working fine?
const toggleBtn = document.querySelector(".toggle-btn");
const slideoutSidebar = document.querySelector(".slideout-sidebar");
console.log(toggleBtn);
const slideTheBar = function () {
toggleBtn.classList.toggle("toggle-slide");
slideoutSidebar.classList.toggle("slideout-slide");
};
toggleBtn.addEventListener("click", slideTheBar);
.slideout-sidebar {
display: block;
height: 200px;
width: 100px;
position: absolute;
top: 0;
right: -200px;
background: #F05D7C;
color: #fff;
font-size: 20px;
transition: all 0.3s ease-in;
}
.slideout-slide.slideout-slide {
right: 0
}
<button class="toggle-btn">Toggle</button>
<div class="slideout-sidebar">Slide me in</div>
How to add event listener to all elements
You need to loop over the elements (you should have an error on your console).
Instead of
document.querySelectorAll(".fa-trash").addEventListener('click', function() {
alert('CLICKED');
});
you should use
document.querySelectorAll(".fa-trash").forEach(
function(el){
el.addEventListener('click', function() {
alert('CLICKED');
})
}
)
Related Topics
Position Fixed Not Working in Mobile Browser
How to Select All Text in Contenteditable Div
Using JavaScript to Mark a Link as Visited
Target='_Blank' to Show in New Window, Not New Tab, Possible
Open a New JavaScript Window(.Open) Along with Its CSS Styling
Es6 Module Import Giving "Uncaught Syntaxerror: Unexpected Identifier"
How to Limit Options Selected in a HTML Select Box
How to Disable Copy Paste (Browser)
Js: Get Array of All Selected Nodes in Contenteditable Div
Safari: Absolutely Positioned Divs Not Moving When Updated via Dom
Using CSS Modules How to Define More Than One Style Name
How to Set Textarea Scroll Bar to Bottom as a Default
Dynamically Add CSS to Page via JavaScript
How to Get Value at a Specific Index of Array in JavaScript
React - Prevent Event Trigger on Parent from Child
Is There an Equivalent of the _Nosuchmethod_ Feature for Properties, or a Way to Implement It in Js