Javascript event handler - why does this work?

I am new to javascript as you can understand from the code below. I wanted to create an event handler for the 6 buttons that I have on the page. When you click on the button, the display properties of the code block under the button change from "none" to "block". To do this, I needed to associate each button with one html section (in this case, tags with unique identifiers - pt1, pt2, etc.).

I struggled with this for a while and got the code below to work. And that is the problem! It turns out that I was still wrong. But as a newbie, when it worked, I thought I had done something. Since I spent several hours doing this, I need to know why the code below worked (so that I will feel like I learned something). I will highlight the part of the code that I can’t, for my life, training, why it worked.

var buttons = document.getElementsByClassName("CSS");

for (var i = 0; i < buttons.length; i++) {
    // Generate strings associated with the button ids and the event handlers for each button
    var buttonID = "button" + i;
    var clickHandlerID = "clickHandler" + i;
    var buttonEH = document.getElementById(buttonID);
    // Identify the button elements by id

    // As clickHandlerID is a string, to get the browser to recognise it as a function name
    var clickHandler = window[clickHandlerID];

    buttonEH.addEventListener("click", clickHandler, false);
}

/*****************************************************************************/

// Why does this work?
// clickHandler1, clickHandler2, etc are not referenced in my event handler.
// My botched attempt to create them in the event handler (var clickHandler = window[clickHandlerID];)
// resulted in "undefined" values (from console.log(clickHandler)).
// Yet it worked?!?! (I did eventually find the correct approach, a simple 10 line solution,
// but I am troubled that I don't understand what is going on here. Any help would be greatly appreciated!!)

/*****************************************************************************/


function clickHandler1 () {
    if (pt1.style.display === "block") {
        pt1.style.display = "none";
    } else {
        pt1.style.display = "block";
    }
}

function clickHandler2 () {
    if (pt2.style.display === "block") {
        pt2.style.display = "none";
    } else {
        pt2.style.display = "block";
    }
}
+4
source share
1 answer

var buttons = document.getElementsByClassName("CSS");

for (var i = 0; i < buttons.length; i++) {
    // Generate strings associated with the button ids and the event handlers for each button
    var buttonID = "button" + i;
    var clickHandlerID = "clickHandler" + i;
    var buttonEH = document.getElementById(buttonID);
    // Identify the button elements by id

    // As clickHandlerID is a string, to get the browser to recognise it as a function name
    var clickHandler = window[clickHandlerID];
    console.log(clickHandler);

    buttonEH.addEventListener("click", clickHandler, false);
}

/*****************************************************************************/

// Why does this work?
// clickHandler1, clickHandler2, etc are not referenced in my event handler.
// My botched attempt to create them in the event handler (var clickHandler = window[clickHandlerID];)
// resulted in "undefined" values (from console.log(clickHandler)).
// Yet it worked?!?! (I did eventually find the correct approach, a simple 10 line solution,
// but I am troubled that I don't understand what is going on here. Any help would be greatly appreciated!!)

/*****************************************************************************/


function clickHandler0 () {
    if (pt0.style.display === "block") {
        pt0.style.display = "none";
    } else {
        pt0.style.display = "block";
    }
}
function clickHandler1 () {
    if (pt1.style.display === "block") {
        pt1.style.display = "none";
    } else {
        pt1.style.display = "block";
    }
}

function clickHandler2 () {
    if (pt2.style.display === "block") {
        pt2.style.display = "none";
    } else {
        pt2.style.display = "block";
    }
}
#pt0, #pt1, #pt2, #pt3 {
    display: none;
}
<button id="button0" class="CSS">button 1</button>
<button id="button1" class="CSS">button 2</button>
<button id="button2" class="CSS">button 3</button>

<div id="pt0">PT1</div>
<div id="pt1">PT2</div>
<div id="pt2">PT3</div>
Run codeHide result

All functions and variables defined in the top-level area become object properties window. So window['clickHandler1']equivalently clickHandler1. Your code:

var clickhandler = window[clickHandlerID];

when clickHandlerIDset to type string "clickHandler1", "clickHandler2"etc.

+3
source

All Articles