1

I've read several posts about GetElementsByClassName but I am struggling to understand how to iterate through what it returns.

I am writing pure javascript code so that my navigation bar will take "fixed" positioning when the user scrolls. However, when this change occurs, the navigation bar list items need to change formatting so that their corners are curved on the bottom instead of the top. I need to iterate through the return of getElementsByClassName to change each constituent elements individually but my for loop doesn't work. Do I need a For ... In loop maybe?

What I learnt from other posts:

  • getElementsByClassName does NOT return an array. It returns an HTMLcollection.

  • this may be much easier with jQuery (I'm trying to learn JavaScript as I build this site so its important that I don't use jQuery at this point).

The code in the JSFiddle below will run if you remove the for loop that I am trying to use to iterate through the HTMLcollection.

TLDR: What should my for loop look like in order to iterate through the HTMLcollection in the following fiddle?

JSFiddle:

https://jsfiddle.net/mcgettrm/e8dabdkn/

Code:

window.addEventListener('scroll', function (evt) {
  var distance_from_top = document.body.scrollTop;
  if (distance_from_top <= 80) {
    document.getElementById("navBar").style.position = "static";
    document.getElementById("navBarList").style.borderBottom = "solid black 4px";
    document.getElementById("navBar").style.borderTop = "initial";
  }


    else if(distance_from_top > 80) {
    document.getElementById("navBar").style.position = "fixed";
    document.getElementById("navBar").style.top = "0px";
    document.getElementById("navBar").style.borderTop = "solid black 4px";
    document.getElementById("navBarList").style.borderBottom = "initial";
    var myCollection = document.getElementsByClassName("navBarLink");
    var collectionLength = myCollection.length;
    document.getElementById("consoleInfo").innerHTML = collectionLength;
    document.getElementById("consoleInfo").innerHTML = myCollection[0];
    for(var i = 0, i <= collectionLength, i++){
        myCollection.item(i).style.borderTopLeftRadius = "initial";
        myCollection.item(i).style.borderTopRightRadius = "initial";
        myCollection.item(i).style.borderBottomLeftRadius = "1em";
        myCollection.item(i).style.borderBottomRightRadius = "1em"; 
        }
    } 

});

2 Answers2

3

Regarding what you actually asked...

...which was how to loop through the collection:

You have a bunch of options, most of which are outlined in this answer under "For Array-Like Objects".

Briefly, some choices, assuming we start with:

var myCollection = document.getElementsByClassName("navBarLink");

forEach:

// forEach:
Array.prototype.forEach.call(myCollection, function(element) {
    // Use element here
});

for loop:

var i;
for (i = 0; i < myCollection.length; ++i) {
    // Use myCollection[i] here
}

Note that that's 0 through < myCollection.length, not <= myCollection.length.

Or get a true array using Array.from or Array.prototype.slice. Details in the linked answer.

Regarding what you're actually doing...

I would strongly recommend that you not do a huge amount of inline styling like that. Instead, your JavaScript could be this simple:

window.addEventListener('scroll', function (evt) {
  var distance_from_top = document.body.scrollTop;
  document.body.classList.toggle("near-top",     distance_from_top <= 80);
  document.body.classList.toggle("not-near-top", distance_from_top > 80);
});

(If you have to support really old browsers, you'll need a classList shim or just manipulate body.className directly.)

Then, do the rest in your CSS, for instance your #navBar stuff:

body.not-near-top #navBar {
    /* styles for when we're not near the top */
}
body.near-top #navBar {
    /* style for when we are near the top */
}

Technically, you can do away with one of those classes if you like, just style based on body #navBar { ... } and then override in the class you keep.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

To access an array item by its index you should use myCollection[i] instead of myCollection.item(i).

Also your for-loop sould separate terms by ; not by ,.

You've written for(var i = 0, .., it should be for(var i = 0; ..

Hope it helps.