Search code examples
javascripthtmleventhandler

Can't understand Javascript eventhandler with for loop code


I'm trying to learn JavaScript and I saw a code to change the css style of a web page depending on the button you press.

I can't understand why or how a for loop indicate witch button was press. Here is the javascript part:

var buttons = document.getElementsByTagName("button");

var len = buttons.length;

for (i = 0; i < len; i++) {
  buttons[i].onclick = function() {
    var className = this.innerHTML.toLowerCase();
      document.body.className = className;
  };
}

http://jsfiddle.net/qp9jwwq6/

I looked on the net and w3 school but they don't explain that code with a for loop. Can someone explain it to me?

Thank you


Solution

  • Lets break it down.

    First we need to have access to the DOM element on the page, so we do that by using a method on the document itself which will return the element we want to manipulate.

    var buttons = document.getElementsByTagName("button");
    

    The buttons var will be a list of ALL the buttons on the page. We want to do something with all of them, so first we cache the length of the list, i.e, count how many buttons we have.

    var len = buttons.length;
    

    Then we basically say: set i to 0, and step it up one until its equal to the number of buttons we have.

    for (i = 0; i < len; i++) {
    

    Now, to access one button from the list, we need to use the brackets notation. So buttons[0] is the first element, buttons[1] is the second, etc. Since i starts at 0, we put i in the brackets so that on each iteration it will access the next button in the list.

      buttons[i].onclick = function() {
        var className = this.innerHTML.toLowerCase();
          document.body.className = className;
      };
    }
    

    This is equivalent of doing:

     buttons[0].onclick = function() {
        var className = this.innerHTML.toLowerCase();
          document.body.className = className;
      };
    
     buttons[1].onclick = function() {
        var className = this.innerHTML.toLowerCase();
          document.body.className = className;
      };
    
     buttons[2].onclick = function() {
        var className = this.innerHTML.toLowerCase();
          document.body.className = className;
      };
    
    // etc.
    

    But of course that is super inefficient, and we may not know how many buttons the page has. So we get all the buttons there, find out how many there are, then go through each button and assign an event handler to it along with a new class.

    Now, looking at the onclick handler itself we can see that it first finds the HTML within the button being clicked, turns it into lowercase letters, and assigns it to a variable:

    var className = this.innerHTML.toLowerCase();
    

    By using this we're ensuring that each button will know to get it's own innerHTML when clicked. We're not tracking which button is which, we're just telling each button to check it's own content.

    Then what it does is change the class of the body HTML element to whatever it is that we just parsed

    document.body.className = className;
    

    So say you have something like

    <button>success</button>
    <button>failure</button>
    <button>warning</button>
    

    Clicking the first button would set the <body> element's class to success, clicking the second would set it to failure, and the third would set it to warning.