Reputation: 508
If I have a list of similar elements, such that:
<outer-container>
<element attribute="x" />
<element attribute="x" />
.
.
.
<element attribute="y" />
<element attribute="z" />
</outer-container>
How can I wrap the elements with attribute="x"
so they are within their own container?
<outer-container>
<inner-container>
<element attribute="x" />
<element attribute="x" />
</inner-container>
.
.
.
</outer-container>
Upvotes: 0
Views: 196
Reputation: 3694
I changed your HTML to make it easier to test.
<div>
<input attribute="x" />
<input attribute="x" />
<p>divider</p>
<input attribute="y" />
<input attribute="z" />
</div>
Assuming you want all of the elements of that kind in one container, positioned where the first one was found, you can do this.
// invoked like this
wrapAll('input[attribute=x]', 'span');
// implemented like this
function wrapAll(selector, wrapper) {
if (typeof wrapper === 'string')
wrapper = document.createElement(wrapper);
else if (!wrapper || !wrapper.nodeType)
throw "Illegal 'wrapper' argument."
var els = document.querySelectorAll(selector);
els[0].parentNode.insertBefore(wrapper, els[0]);
for(var i = 0, len = els.length; i < len; i++)
wrapper.appendChild(els[i]);
}
If you wanted different consecutive groups to be wrapped together, you can do this.
// invoked like this
wrapAdjacent('input[attribute=x]', 'span');
// implemented like this
function wrapAdjacent(selector, wrapper) {
if (typeof wrapper === 'string')
wrapper = document.createElement(wrapper);
else if (!wrapper || !wrapper.nodeType)
throw "Illegal 'wrapper' argument."
var els = document.querySelectorAll(selector);
for (var i = 0, len = els.length; i < len; ) {
var this_wrapper = wrapper.cloneNode(false);
els[i].parentNode.insertBefore(this_wrapper, els[i]);
do {
this_wrapper.appendChild(els[i]);
i++;
}
while (nextEl(this_wrapper) === els[i])
}
}
function nextEl(el) {
while (el && (el = el.nextSibling) && el.nodeType !== 1) {}
return el;
}
Upvotes: 1
Reputation: 22271
If jQuery is an option:
$('[attribute="x"]').wrapAll('<inner-container/>');
Demo: http://jsfiddle.net/iambriansreed/Hgp7B/
Upvotes: 2