0
window.onload = function() {
    // set default for landing page: 
    window.location.replace("#Overview");
    // register click event listener for top navigation:
    var navBarButtons = ["class1","class2","class3","class4","class5","class6","class7","class8","class9"];
    var navBarTargets = ["id1","id2","id3","id4","id5","id6","id7","id8","id9"];
    registerNavBar(navBarButtons, navBarTargets);
}
function registerNavBar(navBarButtons, navBarTargets){
    for (var i=0; i<navBarButtons.length; i++){
        sourceElement=document.querySelector("#left_nav .".concat(navBarButtons[i]));
        sourceElement.addEventListener("click",clickNavBarButton({targets:navBarTargets,index:i}))
    }
}
function clickNavBarButton(event){
    clearPages(event.targets);
    document.querySelector("#".concat(event.targets[event.index])).classList.add("active");
}
function clearPages(navBarTargets) {
    for (i=0; i<navBarTargets.length; i++){
        var target = "#".concat(navBarTargets[i]),classList=document.querySelector(target).classList;   
        if (classList.contains("active")){
            classList.remove("active")
        }
    }
}

Im trying to to add an onclick events to elements in my navigation bar which looks like this:

 <div id="left_nav">
                <a href="#Overview" title="Overview"><span class="class1"></span></a>

The registerNavBar() function fails to add onclick events to the elements getting returned by the #left_nav .classn selectors. The .active class is defined as

.active {
    display: block!important
}

while the default state is

display: none

so adding/removing the .active class toggles visibility. Using external libraries is not an option.

Currently all the functions in the loop are beeing performed without throwing errors and i end up with the element with #id9 beeing displayed, but the buttons won't trigger the onclick events when clicked. How to properly add eventListeners to all elements in the Array?

Niko
  • 57
  • 1
  • 6
  • 1
    You're calling the function instead of passing it. Using `.bind()` would be a simple solution. `sourceElement.addEventListener("click", clickNavBarButton.bind(sourceElement, {targets:navBarTargets,index:i}))` –  Aug 01 '16 at 12:27
  • And change the name of the parameter in `clickNavBarButton` from `event` to something else, since that's not the actual event object. –  Aug 01 '16 at 12:28

1 Answers1

1

You can create a closure to keep the event Object data

function registerNavBar(navBarButtons, navBarTargets){
    for (var i=0; i<navBarButtons.length; i++){
        sourceElement=document.querySelector("#left_nav .".concat(navBarButtons[i]));
        sourceElement.addEventListener("click",clickNavBarButton({targets:navBarTargets,index:i}))
    }
}
function clickNavBarButton(event){
  return function(){
    clearPages(event.targets);
    document.querySelector("#".concat(event.targets[event.index])).classList.add("active");
    }
}
Vladu Ionut
  • 8,075
  • 1
  • 19
  • 30