Search code examples
javascriptcss-selectorstampermonkey

How can I select a nested child element of a parent element that has a dynamic ID?


I'm currently toying around with Zendesk, and trying to make changes to a text element on the page. Sadly, Zendesk's elements are dynamic enough that the name of the main element will change on each page load.

Thankfully the structure of the element trees stay pretty static, but it's only the parent element's name that's changing:

#ember6030 > div.comment > div > p
#ember3483 > div.comment > div > p

Currently, here's where I'm at so far:

var item = document.querySelectorAll("[name^=ember] > div.comment > div > p");
var itemtext = item.innerHTML;
console.log(itemtext);

I'm sure I'm missing something, but wouldn't my selector var be correct?

Something like finding an element that begins with "ember" but then follows the rest of the parent-child tree just fine.


EDIT: Things are being a bit more stubborn than I thought, but I've got some extra details if this helps: For the div.comment > div > p elements, a handful of those load up. For right now, I'd like to try targeting just one, but if I can get the text contents of all these elements in console messages, that'd be awesome.


Solution

  • For those CSS paths you would use:

    var item = document.querySelector("[id^=ember] > div.comment > div > p");
    var itemtext = item.textContent;
    console.log(itemtext);
    

    since # is the CSS selector for the id attribute, not the name.

    See also David Klinge's answer about NodeLists.

    So the final code is:

    var items = document.querySelectorAll("[id^=ember] > div.comment > div > p");
    items.forEach (item => {
      var itemtext = item.textContent;
      console.log(itemtext);
    } );
    

    Finally, for what you seem to be trying to do, you probably want textContent instead of innerHTML. This avoids false hits on attributes, comments, etc.