Ad

Selecting Dynamic Class Names Generated By React From A User Script?

I tend to write my own user scripts (aka Violentmonkey / Tampermonkey scripts; formerly Greasemonkey scripts). I often end up selecting elements by class name while doing so - either using native javascript or having the script load jQuery and using that.

I've noticed that sometimes I see dynamically generated class names like "SeriesIndexFooter-footer-3WmRg" with the bolded bits appearing to be some randomly generated part (I think this gets generated by React? I haven't used React myself but have sometimes seen "React" in other element names when encountering these). Obviously, I can just hard-code these classnames in my script AS-IS and it will work... but my concern is that if a site / local server app gets updated later that this will break my user script.

e.g.

// @run-at      document-end
var footer = document.querySelectorAll('.SeriesIndexFooter-footer-3WmRg');
 
//OR
// @run-at      document-end
// @require     https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js
var footer = jQuery('.SeriesIndexFooter-footer-3WmRg');

Is there a better solution that doesn't rely on hard-coding or avoiding class names entirely but also reduces the risk that my script will break because the random portion of the class name changes?

Ad

Answer

There is no way you can predict class suffix that you are talking about.

That is used for purpose of encapsulating styles so that it applies only for that specific element or group of elements.

What you can do in your case is to use few CSS selectors that relay on searching values in attributes. In your case it would look something like this:

document.querySelectorAll('[class*=SeriesIndexFooter-footer]')

If you need to be more specific you can chain selectors. For example you can target a type of element div. There is no limit in chaining selectors to be more precise in selecting what you need.

document.querySelectorAll('div[class*=SeriesIndexFooter-footer]')

With this line you will select all elements where class attribute has a sub-string "SeriesIndexFooter-footer" and is div.
Here is W3Schools doc for that

You can find more selectors that suite your cases on W3Schools doc here

Other word searching CSS selectors that you can use are:

[attribute=value]   [target=_blank] Selects all elements with target="_blank"
[attribute~=value]  [title~=flower] Selects all elements with a title attribute containing the word "flower"
[attribute|=value]  [lang|=en]  Selects all elements with a lang attribute value equal to "en" or starting with "en-"
[attribute^=value]  a[href^="https"]    Selects every <a> element whose href attribute value begins with "https"
[attribute$=value]  a[href$=".pdf"] Selects every <a> element whose href attribute value ends with ".pdf"
[attribute*=value]  a[href*="w3schools"]    Selects every <a> element whose href attribute value contains the substring "w3schools"
Ad
source: stackoverflow.com
Ad