0

I want to select an element using querySelector(...) Let us assume to have a html-fragment like:

<div class="Class1_a123 Class2_z987">Div1 content</div>
<div class="Class1_a123">Div2 content</div>

I want to select only the first div, if it (and this is set dynamically) has the second class. So I wrote the selector as follows:

document.querySelector("div[class^='Class2']");

The result: Nothing is selected. So I wonder, whether there is a hierarchy, which class stands in front of the class list. I thought it checks for all contained classes, whether they start with the expression I need.

Is there a fundamental mistake in my mind and/or understanding, how selectors are working?

If this is right, that the order of classes inside an elements classlist can be important for the layouting/styles of the web-site? In this case I have to think about all code I've written in past, where I used the class^='...' selectors and have it to replace by class*='...' to let it work as expected.

Any suggestions/corrections are welcome.

ToxicHead
  • 1
  • 3
  • Neither attribute starts with "Class2". They both start with "Class1" – Taplar Feb 28 '20 at 21:43
  • Your selector is based on the literal value of the `class` attribute. Using the `.` notation would work as you expect, though you cannot look for partial class names. There's no good reason to do that: your elements can have as many class names as you want, so use something like `"Class2 Class2-foo Class2-bar"` and then query for `".Class2"`. – Pointy Feb 28 '20 at 21:45
  • @Taplar the space between class names "should" denote them as separate classes and the "starts" with would work in a stylesheet. However, I expect javascript is treating the whole thing as a string... – Bryce Howitson Feb 28 '20 at 21:45
  • @BryceHowitson This is not a class selector. This is an attribute selector. It is evaluating against the string value of the attribute. Not individual classes. The attribute just happens to be the class attribute, but that does not change the attribute selector behaviour – Taplar Feb 28 '20 at 21:46
  • @BryceHowitson exactly: that's what `[attrName^=value]` is supposed to mean. It does not work differently for the `class` attribute. – Pointy Feb 28 '20 at 21:46
  • 2
    I see my mistake! The Class List I saw as Array of Classes (Strings), but the selector is simply a text selector for a String with spaces in it... Thank You all for the quick clarification! – ToxicHead Feb 28 '20 at 21:49
  • @Taplar right the CSS parser would be ok with that but this is a javascript attribute with a string value. Meaning a RegEx or similar would be required. – Bryce Howitson Feb 28 '20 at 21:50
  • `document.querySelector("div[class*='Class2']")`; – Scott Marcus Feb 28 '20 at 21:50
  • @BryceHowitson https://jsfiddle.net/j8ph3vdL/ not really, they behave the same – Taplar Feb 28 '20 at 21:52
  • I'm well aware of how it works INSIDE CSS. I'm pointing out that javascript doesn't use the CSS parser for matching elements. – Bryce Howitson Feb 28 '20 at 21:54
  • Given that they both behave the same way, how do you know that? Not that I don't agree they probably don't use the same thing, but if you were just looking at that evidence you wouldn't have any reason to say they didn't use the same thing. @BryceHowitson – Taplar Feb 28 '20 at 21:57
  • Fair point. @Taplar. They do seem to act the same way. But it also seems foolish to assume they always will work the same way, especially when javascript has string manipulation tools that would get the same result. I guess I wasn't overly clear one that :-) – Bryce Howitson Feb 28 '20 at 21:59
  • Conversly, that means I have to think about code I've written, because a class toggle anywhere via `div1Element.classList.remove("Class1_a123");div1Element.classList.add("Class1_a123");` will change the order inside the class attribute to: `
    Div1 content
    ` and any selector `document.querySelector("div[class^='Class1']")` will never find the element when I'm looking for the "Class1*" occurence!
    – ToxicHead Feb 28 '20 at 22:18

1 Answers1

0

So basically, you are trying to query element which has attribute "class" starts with "Class2". To make it works, you need to change the order of the classes.

<div class="Class2_z987 Class1_a123">Div1 content</div>
<div class="Class1_a123">Div2 content</div>
Alex - Tin Le
  • 1,982
  • 1
  • 6
  • 11