Задать вопрос
@tungens

Как найти и сгруппировать элементы с одинаковым классом?

Всем привет. Помогите пожалуйста разобраться. Есть верстка.
<div class="parent">
    <p class="some"></p>
    <div class="child"></div>
    <div class="child"></div>
    <p class="some"></p>
    <p class="some"></p>
    <div class="child"></div>
    <div class="child"></div>
    <p class="some"></p>
    <div class="child"></div>
</div>

Как найти элементы с классом child и сделать им обертку? Нужно чтоб получилось как то так
<div class="parent">
    <p class="some"></p>
    <div class="wrapper">
        <div class="child"></div>
        <div class="child"></div>
    </div>
    <p class="some"></p>
    <p class="some"></p>
    <div class="wrapper">
        <div class="child"></div>
        <div class="child"></div>
    </div>
    <p class="some"></p>
    <div class="wrapper">
        <div class="child"></div>
    </div>
</div>
  • Вопрос задан
  • 63 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
Где, кого и во что надо обернуть:

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);
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы