0

EDIT: The problem was that calling all the divs with a specific class was creating an HTMLCollection, not an array.

I'm making a menu of text items that displays text on the document depending on which item is selected. The following function fires when an item is selected. Ideally, it should:

  1. Put all highlighted menu items into an array and toggle their highlighted class off later. (This means if the menu item is already highlighted, it will get toggled off, and if another menu item is highlighted, it will get toggled off so that the new menu item can be toggled on).
  2. If the selected menu item is not highlighted, it will get toggled to be highlighted and display the information. If it's already highlighted, it will hide the information and get toggled off like the other items in the array.
function togglePlaceholder(id){
    let div = document.getElementById(id);
    let otherDivs = document.getElementsByClassName('highlighted');
    if($(div).hasClass('highlighted')){
        hideNewCode();
    } else {
        div.classList.toggle('highlighted');
        showNewCode(id);
    }
    for (let i = 0; i < otherDivs.length; i++) {
        otherDivs[i].classList.toggle('highlighted');
    }
}

However, what happens instead, inexplicably, is that the selected non-highlighted item goes into the else statement, toggles to highlighted, shows the information, and then promptly gets toggled off with the other items in the array, even though the array of items was already called when the div wasn't highlighted! How can the line calling otherDivs still be running six lines later? The array should already be declared and ready to go. It shouldn't still be looking for other divs with the 'highlighted' class.

How can this bug be bypassed?

SOLUTION:

let blueDivs = document.getElementsByClassName('blueSub');
let otherDivs = [];
for (let i = 0; i < blueDivs.length; i++){
    otherDivs.push(blueDivs[i]);
}
  • Logic seems a little weird, seems like you should not be toggling, but removing. – epascarello Jul 13 '18 at 23:49
  • One thing that might help is to not mix jQuery and JavaScript. you can replace `$(div).hasClass('highlighted')` with `div.classList.has('highlighted')`. It might be easier to remove the class from everything, then add it to the correct one. – Heretic Monkey Jul 13 '18 at 23:49
  • 3
    `getElementsByClassName()` returns a "live" NodeList. This means that if you toggle the class off from an element, it gets removed from `otherDivs`. You should convert it to an array if you don't want this to happen. – Barmar Jul 13 '18 at 23:51
  • `getElementsByClassName` doesn't return an array. The returned [HTMLCollection](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection) reflects the state of the DOM as it changes. There's probably a good dupe around here somewhere. – user2357112 Jul 13 '18 at 23:51

0 Answers0