【问题标题】:Selecting a childnode by inner text from a NodeList通过 NodeList 中的内部文本选择子节点
【发布时间】:2020-02-07 23:01:06
【问题描述】:

第一部分[已解决]

鉴于此 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>

我可以选择所有部分

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

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

我想要完成的是只选择包含“something3”字符串的部分

这是我的第一次尝试:

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

如何过滤选择以仅选择我需要的节点

第二部分:

很抱歉不断更新问题,但这似乎是我实际技能之外的问题.. 现在我得到了节点,我需要做的是在部分中设置 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']
    
  • 【问题讨论】:

    • 你能遍历select列表吗?
    • 我编辑了一些我需要实现的目标,因为之前可能还不是很清楚
    • 看我的回答

    标签: javascript dom filtering nodelist


    【解决方案1】:

    我认为这种方法应该会引导您找到解决方案。 提供您的 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

    【讨论】:

    • 谢谢!我得到了我需要处理的部分,现在我要定制订单。如果我要遇到任何问题,我可以问你吗?
    • 感谢您一直试图帮助我找到一种编码方式!现在它给了我这个错误:TypeError: Argument 1 of Node.appendChild is not an object.
    • 我刚刚尝试了答案中的代码。它工作得很好!刷新页面,我想你没有得到最新版本(我有一段时间做了一些编辑)
    • 实际上可能是find 返回undefined。这意味着 innerHTML 不包含您正在搜索的字符串。我进行了编辑,以防止出现这种错误(undefined 不是Node 类型)
    • 真的令人印象深刻!有效!如果可以的话,我想再问你一件事来提高我的知识。如果我不是用自定义顺序订购它,而是以 desc 数字方式订购它(假设字符串有单词和数字)我应该改变什么?前任。 1) abs 200-201 2)grehgrhr 203-204 3)abs-ege 202 它应该给我这个 --> 1)grehgrhr 203-204 2)abs-ege 202 3)abs 200-201 你真的无论如何都有帮助!非常感谢您的努力,谢谢!
    【解决方案2】:

    您可以将该列表过滤为:

    • 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)
    
    

    :)

    【讨论】:

    • 我试过你的代码,但如果我尝试 console.log 它给了我“未定义”而不是“

      something3

        。 ..
      ”但也许我想在我的问题中这么清楚
    • 您是要获得过滤后的结果列表,还是只是将它们从 DOM 中删除?此代码实际上将它们从 DOM 中删除。
    • 好吧,我可能被误解了,我需要得到一个过滤的结果列表,而不是从 DOM 中删除它们。因为在那之后我必须工作并更改 li 订单。
    • 刚刚编辑了回复,如果有帮助请告诉我!
    【解决方案3】:

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

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

    This 回答更好地解释了它背后的魔力。

    【讨论】:

      猜你喜欢
      • 2018-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多