0

Im looking a way to get an element id by a partial inner html

For exemple, I have this template

<div id="unpredictable-id1">
    <label>
        <span id="unpredictable-id1"> (unpredictable text) </span> <!-- this span have has the same id than div but has unpredictable content -->
        <span>persistant text</span> <!-- this span have no id, no class, no identifier -->
    </label>
</div>

I cant guess the <div> id (no suffix, no prefix, no other attributes ...) the only way I have to get the element is by a text in an inner span (a text that I can find before)

I've tried thing like identifiers = document.querySelectorAll("[textContent*='persistant text']").id; but always return 'undefined'

Does anyone have a lead?

Aelix
  • 3
  • 1
  • 2
  • ID's are unique. If you want to use it multiple times, use class instead of id. – Luca Jung Mar 21 '20 at 17:20
  • https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors – Ezra Siton Mar 21 '20 at 17:27
  • @LucaJung I think there's an assumption being made here that OP doesn't have access to directly change the HTML, which is probably why the need for an around about solution to finding a specific element. – Sam Mar 21 '20 at 17:28
  • [How to get element by inner text](https://stackoverflow.com/questions/3813294/how-to-get-element-by-innertext) – Vaibhav Mar 21 '20 at 17:28

1 Answers1

4

If you can get a reference to a descendant element, then you can use the .closest() method:

// Get all the span elements and loop through them
document.querySelectorAll("span").forEach(function(element){
  // Check the textContent of the element for a match
  if(element.textContent === "persistant text"){
    // Find the nearest ancestor div
    let closest = element.closest("div")
    // ...then do whatever you want with it
    console.log("The " + closest.nodeName + " has an id of: " + closest.id);
  }
});
<div id="unpredictable-id1">
    <label>
        <span id="unpredictable-id1"> (unpredictable text) </span> <!-- this span have has the same id than div but has unpredictable content -->
        <span>persistant text</span> <!-- this span have no id, no class, no identifier -->
    </label>
</div>

FYI: ID's must be unique within a document. Having two elements with the same ID is invalid HTML and defeats the purpose of having IDs in the first place.

Also, [textContent*='persistant text'] didn't work because when you pass something inside of [] into querySelector() or querySelectorAll() you are indicating that you are searching for an attribute of an HTML element. textContent is not an attribute of an HTML element, it's a property of a DOM Element Node. So, nothing matched your search and therefore, you got undefined back.

Scott Marcus
  • 64,069
  • 6
  • 49
  • 71