Question

I use webdriver and often work with css selector and wondering if the amount of code I write to traverse each level can be decreased. Following is the javascript code to access an element and similar code in java would be present in my code.

in the below example I used 3 css selectors to traverse 3 levels and can I combine them together or atleast simplify.

document.querySelector('.datagrid').querySelectorAll(".even")[3].querySelectorAll('tbody tr')
Was it helpful?

Solution

You can use descendant or child selectors (technically "combinators") to combine the first part:

document.querySelectorAll('.datagrid .even')[3].querySelectorAll('tbody tr')

...but it will make the browser work a bit harder than your code does, because the first part of your code (document.querySelector('.datagrid')) will stop looking when it finds the first matching element, and then look for .even elements only within that. The above looks for all .even elements that have .datagrid ancestors. So it may need to search more of the document. Most of the time that doesn't matter, but it's worth pointing out. The above also assumes that there are at least four .even elements in the first .datagrid. If there aren't, your code would throw an error (because of the attempt to call .querySelectorAll on [3], which would be null), whereas the above code might throw an error (if there aren't four in total on the page), or might refer to an .even element in a subsequent .datagrid rather than the first.

The [3] makes it tricky to combine that with the one that follows. It's tempting to use .even:nth-child(3) or .even:nth-of-type(3), but that would be a mistake, because neither of those counts matches for .even and then takes the third one. nth-child matches only elements that are both .even and the third child element of their parent (considering all elements, not just .even ones). nth-of-type does the same thing, but only considering other elements that have the same tag. If you have other non-.even elements with the same tag name, it will be wrong.

Sometimes you hear talk about adding a selector (similar to the :eq provided by jQuery) to do what you're talking about, but the problem (as I understand it) is it would require a fundamental change to how selector engines process selectors (which is right-to-left). (There's also the problem that jQuery is incredibly widely used, and uses 0 as the first element's index, whereas CSS uses 1 in similar situations. So CSS would have to use something other than :eq — perhaps :index? — to avoid confusion.)

OTHER TIPS

Pretty much anything you can do with a css selector you can do with querySelector(), so if you know your css selectors, you should be ok.

"The string argument pass to querySelector must follow the CSS syntax" - extract from the API.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top