【问题标题】:Move 'ul' element into the previous adjacent 'li'` element将“ul”元素移动到前一个相邻的“li”元素中
【发布时间】:2022-01-25 17:51:18
【问题描述】:

我的侧边栏 aside 格式不正确,我无法控制其结构。它会自动从文档正文生成 ul,但错误地将子列表放置在相应的父元素之外。

有效的 html 代码应该是:

<ul>
 <li>
  <a>Text</a>
  <ul>
   <li>
    <a>Text</a>
   </li>
  </ul>
 </li>
</ul>

ul 元素嵌套在前一个 li 元素中。

在我使用的系统中,也有章节标题的功能,应该是主列表中的顶级li元素

<ul>
 <li><a>Text</a></li>  <-- chapter title
 <li><a>Text</a></li>  <-- chapter title
 <li><a>Text</a>       <-- chapter title
  <ul>
   <li>
    <a>Text</a>        <-- sub-chapter title
   </li>
  </ul>
 </li>
</ul>

下面是一个测试 html 结构和一些我一直在尝试工作的 javascript。

目前它正在遍历所有找到的li 元素的循环,并将下一个ul 元素添加到其中。但是,因为它是自上而下地进行,所以它会进入一个不断添加元素的循环。

我尝试使用.previousElementSibling,但在尝试将null 插入到上面的元素时,列表中的许多元素都返回了null

这是我要做的,希望有人可以指导我正确处理这些数据的方法。

// -- get the sidebar list
const sidebarList = document.querySelector('div.sidebar-nav > ul');

const reorder = ((list) => {
    const listItems = list.querySelectorAll(':scope li');
    listItems.forEach((element) => {

    // -- last h6 wont have a next sibling
    if (element.nextElementSibling === null) return;

    // -- if it is a second sub heading skip
    if (element.nextElementSibling.tagName !== 'UL') return;

    // -- add into the next element
    element.innerHTML = element.innerHTML + element.nextElementSibling.innerHTML
    });
})(sidebarList);
/*
------
HOW IT SHOULD RENDER
------
<aside class="sidebar">
 <div class="sidebar-nav">
  <ul>
   <li>
    <a>Heading level 1</a>
    <ul>
     <li>
      <a>Heading level 2</a>
      <ul>
       <li>
        <a>Heading level 3</a>
        <ul>
         <li>
          <a>Heading Level 4 - 1</a>
         </li>
         <li>
          <a>Heading Level 4 - 2</a>
          <ul>
           <li>
            <a>Heading Level 5</a>
            <ul>
             <li>
              <a>Heading level 6</a>
             </li>
            </ul>
           </li>
          </ul>
         </li>
        </ul>
       </li>
      </ul>
     </li>
    </ul>
   </li>
   <li>
    <a>Heading level 1</a>
    <ul>
     <li>
      <a>Heading level 2</a>
      <ul>
       <li>
        <a>Heading level 3</a>
        <ul>
         <li>
          <a>Heading Level 4 - 1</a>
         </li>
         <li>
          <a>Heading Level 4 - 2</a>
          <ul>
           <li>
            <a>Heading Level 5</a>
            <ul>
             <li>
              <a>Heading level 6</a>
             </li>
            </ul>
           </li>
          </ul>
         </li>
        </ul>
       </li>
      </ul>
     </li>
    </ul>
   </li>
  </ul>
 </div>
</aside>
*/
<aside class="sidebar">
  <div class="sidebar-nav">
    <ul>
      <li><a>Heading level 1</a></li>
      <ul>
        <li><a>Heading level 2</a></li>
        <ul>
          <li><a>Heading level 3</a></li>
          <ul>
            <li><a>Heading Level 4 - 1</a></li>
            <li><a>Heading Level 4 - 2</a></li>
            <ul>
              <li><a>Heading Level 5</a></li>
              <ul>
                <li><a>Heading level 6</a></li>
              </ul>
            </ul>
          </ul>
        </ul>
      </ul>
      <li><a>Heading level 1</a></li>
      <ul>
        <li><a>Heading level 2</a></li>
        <ul>
          <li><a>Heading level 3</a></li>
          <ul>
            <li><a>Heading Level 4 - 1</a></li>
            <li><a>Heading Level 4 - 2</a></li>
            <ul>
              <li><a>Heading Level 5</a></li>
              <ul>
                <li><a>Heading level 6</a></li>
              </ul>
            </ul>
          </ul>
        </ul>
      </ul>
    </ul>
  </div>
</aside>

【问题讨论】:

  • 那是不正确放置 &lt;ul&gt; 的丑陋混乱,但浏览器不会接受 ul 作为 ul 的孩子并拒绝其中的一些。问题可能是所有浏览器都拒绝相同吗?我不太清楚最终结果应该是什么样子
  • @charlietfl 是的,对不起,它是如此微小或变化。我正在尝试实现将子 ul 插入到父 li 元素中。这是合规的,而 li 旁边的 ul 不是
  • 我的错。似乎浏览器正在接受嵌套的 UL 。无论如何,在FF。我对这些问题很了解,因为我记得以前 IE 在呈现无效标记时会做与 FF 完全不同的事情。所以在 FF 中做这个 mod 的方法可能在 Safari 或 Opera 中不起作用
  • 是的,我同意!就我的测试而言,无论嵌套性质如何,主要浏览器似乎都能正确呈现它。当ulli 旁边并说这你的父母但它在你之外时,它更归结为能够操纵数据
  • 我对你最终想要的结构感到困惑。它只是一个列表吗?

标签: javascript html css


【解决方案1】:

这似乎有效:

document.querySelectorAll('ul').forEach(function(list) {
  let prev = list.previousElementSibling;

  if (!prev) return;

  if (list.parentNode.nodeName == "UL" && prev.nodeName == "LI") {
    prev.appendChild(list);
  }
});

它遍历每个ul,检查ul 是否有直接的ul 父级和前面的li。如果是,它会将ul 附加到前面的li

https://jsfiddle.net/ago8by90/

【讨论】:

    猜你喜欢
    • 2018-12-20
    • 2019-08-15
    • 2013-05-27
    • 1970-01-01
    • 1970-01-01
    • 2012-08-12
    • 1970-01-01
    • 2016-08-03
    • 1970-01-01
    相关资源
    最近更新 更多