-1

I have 3 divs , the first one is with id , the second two with same class. I've written an EventListeners with javascript for these 3 divs. The eventlistener for my first div , which is related with an ID works , but the second function which is related to getElementsByClassName() doesn't work. Here's my code

document.addEventListener("DOMContentLoaded", function() {
  var firstElement = document.getElementById('firstOne');
  firstOne.addEventListener('mouseout', function() {
    this.style.backgroundColor = 'red';
    this.style.border = '5px outset #00FF1E';
  });

  var secondElements = document.getElementsByClassName('secondOne');
  secondElements.addEventListener('click', function() {
    for (var i = 0; i < secondElements.length; i++) {
      secondElements[i].style.backgroundColor = 'red';
    }
  });
});
#firstOne {
  height: 240px;
  width: 240px;
  border: 5px solid blue;
  background-color: orange;
  display: inline-block;
}
.secondOne {
  height: 240px;
  width: 240px;
  border: 5px solid green;
  background-color: skyblue;
  display: inline-block;
}
<div id="firstOne"></div>
<div class="secondOne"></div>
<div class="secondOne"></div>
Gaurang Tandon
  • 6,504
  • 11
  • 47
  • 84
Nasco.Chachev
  • 666
  • 6
  • 22

2 Answers2

3

document.getElementsByClassName returns a NodeList. Since you are doing secondElements.addEventListener, it will throw an error because you cannot attach events to a NodeList. You always attach events to a Node.

To fix this, loop over the elements of the NodeList using a for-loop (or a .apply-forEach combo if you are comfortable with that), and attach event listener individually.

document.getElementById always returns a Node (since there can only be one element with a particular id in the DOM) and so firstOne.addEventListener works.

Code sample:

var secondElements = document.getElementsByClassName('secondOne');

for(var i = 0, len = secondElements.length, elm; i < len; i++){
    elm = secondElements[i];

    elm.addEventListener('click', your_handler_function_here);
}
Gaurang Tandon
  • 6,504
  • 11
  • 47
  • 84
  • Okay , I understand.So there's no way to apply a style to multiple elements with getElementsByClassName()? So what about querySelector() method ?? If I do a variable with value = document.querySelector('.secondOne').addEventListener('click',function(){..}); will it work? – Nasco.Chachev Dec 14 '15 at 08:19
  • 1
    `document.querySelector` only returns a `Node`, so it would work. But remember that it would grab only the first appearance of the matched element. And the other matching nodes will be missed by that method. As I said, if you want to use `getElementsByClassName`, you can loop over the individual elements of the Nodelist returned by it and then manually attach listener to each of them. – Gaurang Tandon Dec 14 '15 at 08:20
  • which means if I have 2 divs with same class , and use querySelector , will catch only the first div ? And another question is , if i use querySelector() method, can I write the function inside like querySelector('items').addEventListener('click',function(){..}) or , I have to define the function outside this one and use it only by name , like querySelector('items').addEventListener('click',changeColor); – Nasco.Chachev Dec 14 '15 at 08:22
  • 1
    @Nasco.Chachev Yes. I will give you a code example. Wait. – Gaurang Tandon Dec 14 '15 at 08:24
  • 1
    @Nasco.Chachev See updated answer – Gaurang Tandon Dec 14 '15 at 08:28
  • BRo , i have an issue , i've tried to do it with querySelector , but maybe again returns NodeList... var secondElements = document.querySelector('div.secondOne'); secondElements.addEventListener('click',function(){ for(var i = 0;i – Nasco.Chachev Dec 14 '15 at 08:39
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/97847/discussion-between-gaurang-tandon-and-nasco-chachev). – Gaurang Tandon Dec 14 '15 at 12:01
2

getElementsByClassName() return an array-like object of all child elements which have all of the given class names.

use for() to loop it, and add click event;

    var secondElements = document.getElementsByClassName('secondOne');

    for (var i=0;i<secondElements.length; i++) {
       secondElements[i].addEventListener('click',function(){
           for(var i = 0; i < secondElements.length ; i++){
              secondElements[i].style.backgroundColor = 'red';
            }
        });
     }

demo http://jsfiddle.net/yqec6aqs/

Alien
  • 3,658
  • 1
  • 16
  • 33