从 NodeList 中通过内部文本选择子节点

Selecting a childnode by inner text from a NodeList

第一部分[已解决]

鉴于此 HTML

    <div id="search_filters">
     <section class="facet clearfix"><p>something</p><ul>...</ul></section>
     <section class="facet clearfix"><p>something1</p><ul>...</ul></section>
     <section class="facet clearfix"><p>something2</p><ul>...</ul></section>
     <section class="facet clearfix"><p>something3</p><ul>...</ul></section>
     <section class="facet clearfix"><p>something4</p><ul>...</ul></section>
    </div>

我可以select所有部分

const select = document.querySelectorAll('section[class^="facet clearfix"]');

结果是一个有 5 个 children 的节点列表。

我想要完成的是 select 只有包含 "something3" 字符串的 部分

这是我的第一次尝试:

`const xpathResult = document.evaluate( //section[p[contains(.,'something3')]],
        select,  null, XPathResult.ANY_TYPE, null );

如何将 selection 过滤为 select 只有我需要的 node

第二部分:

很抱歉不断更新这个问题,但这似乎是我实际技能之外的问题.. 现在我得到了节点,我需要做的是在部分中设置 li 的自定义顺序:

<ul id="" class="collapse">
  <li>
   <label>
    <span>
     <input>
      <span>
       <a> TEXT
       </a>
      </span>
     </input>
    </span>
   </label>
  </li>
<li>..</li>

假设有 n

  • 有 n 个不同的文本,我有一个自定义订单要遵循我认为最好的方法是查看 innertex 并与我设置的数组匹配正确的顺序。

    var sorOrder = ['text2','text1','text4','text3']
    
  • 您可以将该列表过滤为:

    • DOM 元素:
    Array.from(document.querySelectorAll('section[class^="facet clearfix"]')).filter(_ => _.querySelector('p').innerText === "something3")
    
    • HTML 字符串:
    
    Array.from(document.querySelectorAll('section[class^="facet clearfix"]')).filter(_ => _.querySelector('p').innerText === "something3").map(_ => _.outerHTML)
    
    

    :)

    为了在您的节点列表上使用像过滤器这样的高阶函数,您必须将其更改为数组。你可以通过解构来做到这一点:

    var select = document.querySelectorAll('section[class^="facet clearfix"]');
    
    const filtered = [...select].filter(section => section.children[0].innerText == "something3")
    

    答案更好地解释了它背后的魔法。

    我认为这种方法应该可以引导您找到解决方案。 提供您的 HTML

    <div id="search_filters">
     <section class="facet clearfix"><p>something</p><ul>...</ul></section>
     <section class="facet clearfix"><p>something1</p><ul>...</ul></section>
     <section class="facet clearfix"><p>something2</p><ul>...</ul></section>
     <section class="facet clearfix"><p>something3</p><ul>...</ul></section>
     <section class="facet clearfix"><p>something4</p><ul>...</ul></section>
    </div>
    

    我会写这个js

    const needle = "something3";
    const selection = document.querySelectorAll('section.facet.clearfix');
    let i = -1;
    
    console.info("SELECTION", selection);
    let targetIndex;
    while(++i < selection.length){
      if(selection[i].innerHTML.indexOf(needle) > -1){
        targetIndex = i;
      }
    }
    console.info("targetIndex", targetIndex);
    console.info("TARGET", selection[targetIndex]);
    

    然后您可以播放和交换元素,而无需将它们从 DOM 中移除。

    PS。由于您知道元素的 CSS 类,因此您不需要使用 ^*(开头)选择器。我也改进了。

    第 2 部分:根据内容对子 li 进行排序

    const ul = selection[targetIndex].querySelector("ul"); // Find the <ul>
    const lis = ul.querySelectorAll("li"); // Find all the <li>
    const sortOrder = ['text2', 'text1', 'text4', 'text3'];
    i = -1; // We already declared this above
    while(++i < sortOrder.length){
        const li = [...lis].find((li) => li.innerHTML.indexOf(sortOrder[i]) > -1);
        !!li && ul.appendChild(li);
    }
    

    这将根据 sortOrder 中的内容和位置,按照您需要的顺序移动您想要的元素(仅 sortOrder 中列出的元素)。

    Codepen Here