'Javascript how to wrap elements in groups
I have this DOM:
<div class="section">Section</div>
<div>Text</div>
<div>Image</div>
<div>Text</div>
<div>Gallery</div>
<div class="section">Section</div>
<div>Text</div>
<div>Image</div>
<div>Text</div>
<div>Gallery</div>
but I want to a wrap the elements like this:
<div class="relative">
<div class="section">Section</div>
<div>Text</div>
<div>Image</div>
<div>Text</div>
<div>Gallery</div>
</div>
<div class="relative">
<div class="section">Section</div>
<div>Text</div>
<div>Image</div>
<div>Text</div>
<div>Gallery</div>
</div>
So I tried this:
function getSiblings(elm, withTextNodes) {
if (!elm || !elm.parentNode) return
let siblings = [
...elm.parentNode[withTextNodes ? 'childNodes' : 'children'],
],
idx = siblings.indexOf(elm)
siblings.before = siblings.slice(0, idx)
siblings.after = siblings.slice(idx + 1)
return siblings
}
const sections = document.querySelectorAll('.section')
sections.forEach((section) => {
const elmSiblings = this.getSiblings(section)
// children elements to be wrapped inside the wrapper
const children = elmSiblings.before
const wrapper = document.createElement('div')
wrapper.classList.add('section-wrapper')
section.parentNode.insertBefore(wrapper, section)
wrapper.appendChild(section)
})
but this only wraps the ´section´ element inside the newly created section-wrapper
how can I achieve this?
Solution 1:[1]
Something like this, testing the nextElementSibling
document.querySelectorAll(".section").forEach(sec => {
let next = sec.nextElementSibling; // important to get this before wrapping
const wrapper = document.createElement("div")
wrapper.classList.add("relative")
sec.insertAdjacentElement("beforeBegin", wrapper)
wrapper.append(sec);
while (next && !next.classList.contains("section")) {
const nextSib = next.nextElementSibling; // important to get this before appending
wrapper.append(next)
if (nextSib) next = nextSib;
else next = null
}
})
.relative {
background-color: red
}
.section {
background-color: yellow
}
<div class="section">Section1</div>
<div>Text 1</div>
<div>Image 1</div>
<div>Text 2</div>
<div>Gallery 1</div>
<div class="section">Section2</div>
<div>Text 2.1 </div>
<div>Image 2</div>
<div>Text 2.2</div>
<div>Gallery 2</div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
