Почему это цикл forEach? - PullRequest
       3

Почему это цикл forEach?

1 голос
/ 13 марта 2019

Извиняюсь за плохой код .. Смешная совместимость на этом тестирует мой Vanilla JS metal:

Мне нужно обернуть каждый заголовок и его узлы (до следующего заголовка) в div. Почему функция обтекания создает вложенные div-обертки (помеченные 'section)?

Исходное состояние:

<h1></h1>
<p></p>
<p></p>
<h2></h2>
<p></p>
<p></p>

Например, желаемый результат:

<div class="section">
  <h1></h1>
  <p></p>
  <p></p>
</div>
<div class="section">
  <h2></h2>
  <p></p>
  <p></p>
</div>

Текущий результат:

<div class="section">
  <h1></h1>
  <p></p>
  <p></p>
  <div class="section">
    <h2></h2>
    <p></p>
    <p></p>
  </div>
</div>

Конечно, чем больше массив узлов-братьев, тем глубже вложение. Я знаю, что это что-то простое, но я не могу обернуть (каламбур) голову вокруг этого.

Вот мой код JavaScript:

// Filter for grouping like elements together
var getNextUntil = function (elem, selector, group) {
  // Setup siblings array and get next sibling
  var siblings = [];
  var next = elem.nextElementSibling;
  // Loop through all siblings
  while (next) {
      var isClass = next.className.split(' ').some(function (c) {
          var re = new RegExp(selector);
          return re.test(c);
      });
      // Check if grouping is set
      if (group == false) {
          // If the matching selector is found
          if (isClass == true) break;
           // Otherwise, push to array              
      } else {
          if (isClass == false) break;
      }
      siblings.push(next);
      // Get the next sibling
      next = next.nextElementSibling;    
  }
  return siblings;
};
var headers = document.querySelectorAll("h1, h2, h3, h4, h5, h6");
Array.prototype.forEach.call(headers, function(el, i){
  el.classList.add('header');
  var sibs = getNextUntil(el,'header', false);
  var section = document.createElement('div');
  section.className = 'section';
  function wrap(el, wrapper) {
    el.parentNode.insertBefore(wrapper, el);
    wrapper.appendChild(el);
  }

  wrap(el,section);
  Array.prototype.forEach.call(sibs, function(el, i){
    section.appendChild(el);
  })

});

Любая помощь очень ценится.

1 Ответ

2 голосов
/ 13 марта 2019

Я не уверен, что именно вы пытаетесь достичь, но приведенный ниже код выполняет вашу заявленную цель с помощью Vanilla JavaScript, используя те же функциональные возможности, которые вы используете в плане взаимодействия.

const headers = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
// reference to the parent element
let parent = document.getElementById('within');
// use STATIC DOM NodeList - selects all direct children of the parent
let withinParent = document.querySelectorAll('#within > *');

for (let child of withinParent) {
  // A header will create a new div
  if (headers.includes(child.nodeName.toLowerCase())) {
    if (wrapper) parent.appendChild(wrapper);
    var wrapper = document.createElement('div');
    wrapper.classList.add('section');
    // this is the header element
    wrapper.appendChild(child);
    continue;
  }
  if (child.nodeName !== 'SCRIPT') {
    // Add elements until we find another header
    wrapper.appendChild(child);
  }
}
// include final div for the final header
parent.appendChild(wrapper);
console.log(parent);
.section {
  margin-bottom: 2em;
  padding: 1em;
  background-color: lightblue;
}
<div id='within'>

  <h1>Header 1</h1>
  <p>Sibling 1</p>
  <p>Sibling 2</p>
  <p>Sibling 3</p>

  <h2>Header 2</h2>
  <p>Sibling 1</p>
  <p>Sibling 2</p>

  <h3>Header 3</h3>
  <p>Sibling 1</p>
  <p>Sibling 2</p>

  <h4>Header 4</h4>
  <p>Sibling 1</p>
  <p>Sibling 2</p>
  <p>Sibling 3</p>

</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...