Reputation: 101
I am trying to move two elements on load with Javascript. My HTML looks like this:
<body>
<div class="something">
<nav class="navbar"></nav>
<footer></footer>
</div>
</body>
What am trying to achieve is HTML like this:
<body>
<nav class="navbar"></nav>
<div class="something"></div>
<footer></footer>
</body>
Basically, the nav
element below the opening body tag, and the footer
at the end.
I did try something like this:
var a = document.getElementsByClassName("navbar");
document.body.appendChild(a);
Can anybody try to help me with this?
Upvotes: 1
Views: 6510
Reputation: 1074295
See comments:
// Get the `.something` element and its parent
const something = document.querySelector(".something");
const parent = something.parentElement;
// Get the `navbar` inside it and move it in front of it
const navbar = something.querySelector(".navbar");
parent.insertBefore(navbar, something);
// Get the `footer` inside it and insert it after it
const footer = something.querySelector("footer");
parent.insertBefore(footer, something.nextElementSibling);
<div class="something">
<nav class="navbar"></nav>
<footer></footer>
</div>
After that runs, if you right-click the output pane and look at the HTML, you'll see they're in the requested order (ignore the script
that the snippet puts there).
If you have this repeated on a page, all you have to change is how you get the something
elements to work on, using a loop:
for (const something of document.querySelectorAll(".something")) {
// ...rest of the code goes here unchanged...
}
Note that that requires that the NodeList
from querySelectorAll
is iterable, which it is in modern environments. You can polyfill that for slightly older environments that support iteration but hadn't yet made NodeList
iterable as I describe in this answer. For environments that don't support iterability, that link also shows how to polyfill forEach
if NodeList
doesn't have it, which you'd use like this:
document.querySelectorAll(".something").forEach(something => {
// ...rest of the code goes here unchanged...
});
Upvotes: 2
Reputation: 13222
You can use inserBefore to do this. My answer is like T.J. Crowder answer but this will work if you have multiple instances of those elements by looping over all found instances.
document.querySelectorAll('.navbar').forEach((el) => {
el.parentNode.parentNode.insertBefore(el, el.parentNode);
});
document.querySelectorAll('footer').forEach((el) => {
el.parentNode.parentNode.insertBefore(el, el.parentNode.nextElementSibling);
});
<body>
<div class="something">
something
<nav class="navbar">navbar</nav>
<footer>footer</footer>
</div>
<div class="something">
something2
<nav class="navbar">navbar2</nav>
<footer>footer2</footer>
</div>
</body>
Upvotes: 0