I have a nav menu and want to add a decorative element between each item. Outside of the loop my code seems to work when I target a specific list item with [0], but when used inside the loop using [i] the page never finishes loading.
When i move to JSbin to test, I am getting infinite loop errors.
HTML:
<ul id="menu-mobile-navigation">
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
<li>Etc</li>
</ul>
JS:
var mobileNav = document.getElementById('menu-mobile-navigation');
var mobileNavChildren = mobileNav.children;
// var decoration = document.createElement('div');
// decoration.classList.add( 'decoration' );
// mobileNav.insertBefore( decoration, mobileNavChildren[0].nextSibling ); // works outside loop
for (var i = 0; i < mobileNavChildren.length; i++) {
var decoration = document.createElement('div');
decoration.classList.add( 'decoration' );
mobileNav.insertBefore( decoration, mobileNavChildren[i].nextSibling ); // page never loads, infinite loop error in JSbin
}
The .children
of an element returns a live HTMLCollectio, which will mutate even as you iterate over it if elements get added to it in the middle of looping:
var mobileNav = document.getElementById('menu-mobile-navigation'); var mobileNavChildren = mobileNav.children; console.log(mobileNavChildren.length); mobileNav.appendChild(document.createElement('div')); console.log(mobileNavChildren.length);
<ul id="menu-mobile-navigation"> <li>One</li> <li>Two</li> <li>Three</li> <li>Four</li> <li>Etc</li> </ul>
You want a static collection instead - consider using querySelectorAll
, or spreading into an array:
const mobileNav = document.getElementById('menu-mobile-navigation'); const mobileNavChildren = mobileNav.querySelectorAll('li'); for (var i = 0; i < mobileNavChildren.length; i++) { var decoration = document.createElement('div'); decoration.classList.add( 'decoration' ); mobileNav.insertBefore( decoration, mobileNavChildren[i].nextSibling ); }
<ul id="menu-mobile-navigation"> <li>One</li> <li>Two</li> <li>Three</li> <li>Four</li> <li>Etc</li> </ul>
Though, also note that a <div>
should not be a child of a <ul>
- only list elements should be children of a <ul>
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.