为什么此forEach循环嵌套?

时间:2019-03-12 22:33:07

标签: javascript html arrays foreach

为可怜的代码表示歉意。.对此的可笑兼容性正在测试我的Vanilla JS金属:

我需要在div中包装每个标头及其兄弟节点(直到到达下一个标头)。为什么wrap函数会创建嵌套的wrapper 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 个答案:

答案 0 :(得分:2)

我不确定您到底要实现什么目标,但是下面的代码使用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>