109

Example 1:

element1.addEventListener("input", function() {
  // this function does stuff 
});

Example 2:

element1 && element2.addEventListener("input", function() {
  // this function does stuff
});

It might not be correct grammatically, but is there a way I can give two elements the same event listener at the same time (same line) instead of having to write them apart?

JShobbyist
  • 532
  • 3
  • 9
  • 23
Jamisco
  • 1,658
  • 3
  • 13
  • 17

15 Answers15

170

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
    });
});
GMaiolo
  • 4,207
  • 1
  • 21
  • 37
  • 3
    oh, i was hoping it could be done in a single line. Nevertheless i appreciate the answer – Jamisco Dec 04 '16 at 08:31
  • 13
    If you use ES6 then it's possible: `elementsArray.forEach(el => el.addEventListener('input', functionThatDoesStuff))` – GMaiolo Dec 04 '16 at 08:34
  • 35
    What is your definition of "single line"? Any JS program can be written on a single line by removing line breaks. –  Dec 04 '16 at 08:49
  • 1
    You can't get a list with `document.getElementsByTagName()` eh? I tried that and it didn't work - I had to use `querySelectorAll`. Thanks though for this, it worked for me! – BruceWayne Nov 12 '17 at 21:05
  • 2
    This doesn't work for me... I got elements in array and I have attached "Click" listener on each element but when I click it event never fires! – IamCavic Jan 02 '18 at 23:09
  • @IamCavic your issue seems non-related to this one, you should open a new question – GMaiolo Jan 02 '18 at 23:19
  • Awesome Flavio Copes would add, you can build your selector with `[document.querySelector('.a-class'), document.querySelector('.another-class')].forEach(item => { item.addEventListener('click', event => { //handle click }) })` – djibe Nov 24 '21 at 21:24
44

Event Bubbling is the important concept in javascript, so if you can add event on DOM directly, you can save some lines of code, no need for looping :

document.addEventListener('click', function(e){
  if(e.target.tagName=="BUTTON"){
   alert('BUTTON CLICKED');
  }
})
Ayush Sharma
  • 2,057
  • 15
  • 25
  • 2
    This is a nice technique if you create DOM elements dynamically since you don't need to add eventListeners on user interaction. – squarespiral Feb 12 '21 at 09:51
44

If you don't want to have a separate elementsArray variable defined you could just call forEach from an unnamed array with the two elements.

[ Element1, Element2 ].forEach(function(element) {
   element.addEventListener("input", function() {
      this function does stuff
   });
});
John Ayling
  • 441
  • 4
  • 3
14

One line

document.querySelectorAll("whatever").forEach(elem => elem.addEventListener("input", fn))
Adrian
  • 2,233
  • 1
  • 22
  • 33
  • this one is assuming all elements share same selector, which might not always be the case or even if they did some of them might need to be excluded etc. – Vitaliy Terziev Jan 15 '23 at 15:06
  • 1
    @VitaliyTerziev You are right, my answer is meant to be a little cynic … it is always possible to put everything in "one line", but often not useful. – Adrian Jan 16 '23 at 07:27
4

I cannot claim credit for this solution but I found a great solution here.

https://www.kirupa.com/html5/handling_events_for_many_elements.htm

    var theParent = document.querySelector("#theDude");
    theParent.addEventListener("click", doSomething, false);

    function doSomething(e) {
        if (e.target !== e.currentTarget) {
            var clickedItem = e.target.id;
            alert("Hello " + clickedItem);
        }
        e.stopPropagation();
    }
daniella
  • 403
  • 7
  • 17
4

I always recommend delegation - if the inputs are in the same container, then you can do this

window.addEventListener("DOMContentLoaded", function() { // on page load
  document.getElementById("inputContainer").addEventListener("input", function(e) { // passing the event
    const tgt = e.target;
    const id = tgt.id;
    console.log("You typed in",id)
  });
});
<div id="inputContainer">
  <h1>Start typing or paste</h1>
  <input id="element1">
  <input id="element2">
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
3

Maybe it will help you

let all_btn = document.querySelectorAll("button");
all_btn.forEach(function(btn) {
    btn.addEventListener("click", function() {
        console.log(this.innerHTML + " is clicked")
    });
});

// one line code
// let all_btn=document.querySelectorAll("button");all_btn.forEach(function(n){n.addEventListener("click",function(){console.log(this.innerHTML+" is clicked")})});
<button>button 1</button>
<button>button 2</button>
<button>button 3</button>
Abdul Rehman
  • 139
  • 1
  • 5
2

Example:

const element1 = document.querySelector("#element1");
const element2 = document.querySelector("#element2");

[element1, element2].map(element => element.addEventListener("click", function() {
  /*some expressions :)*/
}))
Noman Gul
  • 390
  • 1
  • 4
  • 12
2

If you are using Javascript through Electron and you have a list of buttons, you can use this code to add an EventListener to each button. I'm actually using this method because classical Javascript methods (map(), forEach() ...) weren't supported anymore.

let buttons = document.getElementsByClassName('className');
for(let i = 0; i<buttons.length; i++){
   buttons[i].addEventListener('click', () => {
      /*put your code here*/
   });
}
MrAnyx
  • 234
  • 3
  • 5
  • This might have been better as a comment to the accepted answer, because it's more likely that the author of the accepted answer might improve their answer. I can see that your answer provides some useful content, but hardly anyone is going to read it at the bottom of eight answers. – David M Jul 02 '19 at 19:18
1

The easiest way so far I've learned.

// Get an array of buttons from the page
var buttons = document.querySelectorAll(".btns");

// Loop through the resulting array
for(var i = 0; i < buttons.length; i++){
  buttons[i].addEventListener("click", function() {
    console.log("Hello World");
  });
}
brookr
  • 1,504
  • 12
  • 14
1

You can add an event listener to multiple elements using the path key of the click event object.

document.addEventListener('click', function(e){
  //e.path[0].id;
  //e.path[0].tagName;
  //e.path[0].className;
  if(e.path[0].className==="my-element"){
    console.log("clicked");
  }
})
abrham t
  • 11
  • 1
0

Example for initializing one unique event listener specific to each element.

You can use the slider to show the values in realtime, or check the console.

On the <input> element I have a attr tag called data-whatever. You can use that to customize each event listener further.

sliders = document.querySelectorAll("input");
sliders.forEach(item=> {
  item.addEventListener('input', (e) => {
    console.log(`${item.getAttribute("data-whatever")} is this value: ${e.target.value}`);
    item.nextElementSibling.textContent = e.target.value;
  });
})
.wrapper {
  display: flex;
}
span {
  padding-right: 30px;
  margin-left: 5px;
}
* {
  font-size: 12px
}
<div class="wrapper">
  <input type="range" min="1" data-whatever="size" max="800" value="50" id="sliderSize">
  <em>50</em>
  <span>Size</span>
  <br>
  <input type="range" min="1" data-whatever="OriginY" max="800" value="50" id="sliderOriginY">
  <em>50</em>
  <span>OriginY</span>
  <br>
  <input type="range" min="1" data-whatever="OriginX" max="800" value="50" id="sliderOriginX">
  <em>50</em>
  <span>OriginX</span>
</div>
Vincent Tang
  • 3,758
  • 6
  • 45
  • 63
0

If you have a DOM Collection, I suggest you to use the for ... of

In this MDN web doc you can see the details, but, for example, if you have:

HTMLCollection(6) [a.example, a.example, a.example, a.example, a.example, a.example]

You can:

let arrayElements = document.getElementsByClassName('example');
for (let element of arrayElements) {
    element.addEventListener("click", function() {
        console.log('Whoa! You clicked me')
    });

And ta-dah! ;)

alex-chama
  • 59
  • 8
0

Here's what I used to set a click evenhandler on every span in my HTML (each span contains an emoji). When you click it, it will alert the emoji in the sample code.

Array.from(document.querySelectorAll("span")).map(element => element.addEventListener("click", function() {
  alert(element.innerHTML);
}));
div{background: whitesmoke;}
span{ont-size:x-large;
    cursor:pointer;}
<div>
  <span>&#128512;</span>
  <span>&#128513;</span>
  <span>&#128514;</span>
  <span>&#128515;</span>
  <span>&#128516;</span>
  <span>&#128517;</span>
  <span>&#128518;</span>
  <span>&#128519;</span>
  <span>&#128520;</span>
  <span>&#128521;</span>
  <span>&#128522;</span>
  <span>&#128523;</span>
</div>
raddevus
  • 8,142
  • 7
  • 66
  • 87
-3

First include jQuery then after you have included, add this script below.

Html code:

<script>
    $('.greadingButton').on('click', function () {
        $('.greadingButton').removeClass('selected');
        $(this).addClass('selected');
    });
</script>
node_modules
  • 4,790
  • 6
  • 21
  • 37
Jenil J
  • 3
  • 2
  • OP didn't ask about jQuery (or any other framework) and there's no reason to bloat code with any framework for such a simple use-case. jQuery has kind of had it's day anyway - ES6 has made it *almost* irrelevant. – Carnix Aug 24 '22 at 12:25
  • @Carnix As somebody who has always just added jQuery by default when writing web apps in the last few years, I've landed on this question because I decided to try and write my latest project with only vanilla JS. However, seeing that there isn't even a nice equivalent to `$(".my-class").on("click", function() {...});` in JS yet is pushing me towards sticking with jQuery for now. You're right that the OP didn't ask about jQuery, but it doesn't mean it's not a useful suggestion. – Philip Stratford Feb 07 '23 at 22:43
  • No one should use JQuery anymore in 2023, jeez. Why ruin your page speed with a lib that is completely replaced by vanilla JS? – AlexioVay Feb 22 '23 at 16:45
  • 1
    @PhilipStratford - Sure there is and you saying there isn't just shows you're not up to date on modern ECMAScript. Check this site out, you might find it interesting. https://youmightnotneedjquery.com/ – Carnix Mar 10 '23 at 20:06