Выбор дочернего узла по внутреннему тексту из списка узлов

Первая часть [решено]

Учитывая этот 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>

Assuming there are n

  • with n different texts and i've a custom orders to follow i think the best way to go it would be look at the innertex and matching with an array where i set the correct order.

    var sorOrder = ['text2','text1','text4','text3']
    

  • person costabrava    schedule 10.10.2019    source источник
    comment
    Вы можете перебрать список select?   -  person Sampgun    schedule 10.10.2019
    comment
    Я немного отредактировал то, что мне нужно достичь, потому что, вероятно, раньше это было неясно   -  person costabrava    schedule 10.10.2019
    comment
    Посмотри на мой ответ   -  person Sampgun    schedule 10.10.2019


    Ответы (3)


    Я думаю, что этот подход должен привести вас к решению. Предоставление вашего 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 здесь

    person Sampgun    schedule 10.10.2019
    comment
    Спасибо! Я получил именно тот раздел, над которым мне нужно работать, теперь я должен сделать индивидуальный заказ. Если я собираюсь решить какие-либо проблемы, могу ли я спросить вас? - person costabrava; 10.10.2019
    comment
    Спасибо, что продолжаете пытаться помочь мне найти способ закодировать его! Прямо сейчас это дает мне эту ошибку: TypeError: аргумент 1 Node.appendChild не является объектом. - person costabrava; 10.10.2019
    comment
    Я только что попробовал код в ответе. Это работает просто отлично! Обновите страницу, я думаю, что вы не получаете последнюю версию (однажды я внес некоторые изменения) - person Sampgun; 10.10.2019
    comment
    На самом деле может быть так, что find возвращает undefined. Это означало бы, что innerHTML не содержит строку, которую вы ищете. Я внес правку, чтобы предотвратить такую ​​​​ошибку (undefined не будет типа Node) - person Sampgun; 10.10.2019
    comment
    Действительно впечатляет! Это сработало! Если можно, я хотел бы попросить вас еще кое-что для улучшения моих знаний. Если вместо того, чтобы заказывать это с помощью пользовательского заказа, я заказываю это числовым способом (при условии, что в строках есть слова и числа), что я должен изменить? Бывший. 1)abs 200-201 2)grehgrhr 203-204 3)abs-ege 202 это должно вернуть мне это --› 1)grehgrhr 203-204 2)abs-ege 202 3)abs 200-201 Ты действительно был в любом случае полезно! Я очень ценю ваши усилия, спасибо! - person costabrava; 10.10.2019
    comment
    Хорошо, прежде всего, вы должны отметить мой ответ как решение, щелкнув значок галочки слева. То, о чем вы просите, немного долго достигается. Я думаю, вы должны опубликовать еще один вопрос. Я помогу тебе в этом! - person Sampgun; 11.10.2019

    Чтобы использовать функцию более высокого порядка, такую ​​​​как фильтр, в вашем списке узлов, вы должны изменить ее на массив. Вы можете сделать это, уничтожив:

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

    Этот ответ лучше объясняет стоящую за ним магию.

    person Gh05d    schedule 10.10.2019

    Вы можете отфильтровать этот список как:

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

    :)

    person Nahuel Veron    schedule 10.10.2019
    comment
    я попробовал ваш код, но если я попытаюсь запустить console.log, он выдал мне undefined вместо ‹section class=facet clearfix›‹p›something3‹/p›‹ul›...‹/ul›‹/section›, но, может быть, я хочу так ясно в моих вопросах - person costabrava; 10.10.2019
    comment
    Вы хотите получить отфильтрованный список результатов или просто удалить их из DOM? Этот код фактически удаляет их из DOM. - person Nahuel Veron; 10.10.2019
    comment
    хорошо, вероятно, меня неправильно поняли, мне нужно получить отфильтрованный список результатов, а не удалять их из DOM... потому что после этого мне придется работать и менять заказы li. - person costabrava; 10.10.2019
    comment
    Только что отредактировал ответ, дайте мне знать, если это поможет! - person Nahuel Veron; 10.10.2019