JS select
    tag following an

    tag containing “foo”

    Tags: , ,



    So I’ve got this little chrome extension project and I’m trying to figure out how to find the first “ul” element on the page that comes after an “h2” element that contains a particular word.

    Example of what the web page would look like…

    <div>
      <h2>Foo</h2> // find the first <h2> tag containing "Foo"
      <ul></ul> // find the first <ul> tag that comes after the <h2>  
    </div>
    

    However the nature of varying page code means that it may looks more like this…

    <h2>Foo</h2> // find the first <h2> tag containing "Foo"
    <div> 
      <ul></ul> // find the first <ul> tag that comes after the <h2> 
    </div>
    

    Or even…

    <div>
      <h2>Foo</h2> // find the first <h2> tag containing "Foo"
    </div>
    <div>
      <ul></ul> // find the first <ul> tag that comes after the <h2>
    </div>
    

    I can get the “h2” element containing “foo” by…

    let hTags = document.querySelectorAll("h2");
    let hTag;
    for (var i = 0; i < hTags.length; i++) {
        if (/foo/i.test(hTags[i].textContent)) {
            hTag = hTags[i];
            break;
        }
    }
    

    But that is where I’m stuck, I can’t figure out how to search the rest of the DOM that follows the found “h2” tag. Sibling selectors won’t work as the “h2” and the “ul” may not be within the same element.

    Also being a chrome extension rules out using anything like jQuery.

    Does anyone know if this is possible? Any thoughts would be very much appreciated!

    Answer

    This should do the trick:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body>
        <div>
          <h2>Foo</h2>
        </div>
        <div>
          <ul></ul>
        </div>
    
        <script>
          const regex = new RegExp('foo', 'i');
          const foundElements = [...document.querySelectorAll('* H2, UL')];
          const firstUL = foundElements
            .slice(1)
            .find(
              (el, i) => el.tagName === 'UL' && foundElements[i].tagName === 'H2' && regex.test(foundElements[i].innerText)
            );
          console.log(firstUL);
        </script>
      </body>
    </html>
    


    Source: stackoverflow