Где, кого и во что надо обернуть:
const parent = document.querySelector('.parent');
const toWrapClass = 'child';
const wrapperTag = 'div';
const wrapperClass = 'wrapper';
Оборачиваем:
[...parent.children].reduce((wrapper, n) => {
if (n.classList.contains(toWrapClass)) {
if (!wrapper) {
wrapper = document.createElement(wrapperTag);
wrapper.classList.add(wrapperClass);
n.before(wrapper);
}
wrapper.appendChild(n);
return wrapper;
}
return null;
}, null);
или
Array.prototype.reduce.call(
parent.querySelectorAll(`:scope > .${toWrapClass}`),
(acc, n, i, a) => (
n.previousElementSibling !== a[i - 1] && acc.push([]),
acc.at(-1).push(n),
acc
),
[]
).forEach(n => {
const wrapper = document.createElement(wrapperTag);
wrapper.className = wrapperClass;
parent.insertBefore(wrapper, n[0]);
wrapper.append(...n);
});
или
const toWrapSelector = `.${toWrapClass}`;
const wrapperHTML = `<${wrapperTag} class="${wrapperClass}"></${wrapperTag}>`;
for (
let curr = parent.firstElementChild, next = null, prev = null, wrapper = null;
next = curr?.nextElementSibling, curr;
prev = curr, curr = next
) {
if (!curr.matches(toWrapSelector)) {
continue;
}
if (!prev?.matches(toWrapSelector)) {
curr.insertAdjacentHTML('beforebegin', wrapperHTML);
wrapper = curr.previousSibling;
}
wrapper.insertAdjacentElement('beforeend', curr);
}