3

Я использую webdriver и часто работаю с селектором css и задаюсь вопросом, можно ли уменьшить количество кода, которое я пишу для прохождения каждого уровня. Ниже приведен код javascript для доступа к элементу, и аналогичный код в java будет присутствовать в моем коде.Как скомбинировать css-селектор

В приведенном ниже примере я использовал 3 селектора css для перемещения по 3 уровням и могу ли я объединить их или по крайней мере упростить.

document.querySelector('.datagrid').querySelectorAll(".even")[3].querySelectorAll('tbody tr') 
+0

[Селекторы CSS в селене] (http://sauceio.com/index.php/2010/01/selenium-totw-css-selectors-in-selenium-demystified/) Полезно? – screenmutt

ответ

7

Вы можете использовать descendant или child селекторы (технически «комбинаторов»), чтобы объединить первую часть:

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

... но это сделает работу браузера немного сложнее, чем ваш код делает потому что первая часть вашего кода (document.querySelector('.datagrid')) перестанет смотреть, когда находит первый элемент, а затем ищет .even элементы только внутри этого. Вышесказанное ищет все.even элементы, которые имеют .datagrid предков. Таким образом, возможно, потребуется найти больше документа. Большую часть времени это не имеет значения, но стоит отметить. Вышеизложенное также предполагает, что в первом .datagrid имеется как минимум четыре элемента .even. Если нет, то ваш код будет сгенерировано сообщение об ошибке (из-за попытки позвонить .querySelectorAll на [3], который был бы null), в то время как приведенный выше код может выдаст ошибку (если не четыре в общей на странице), или может ссылаться на элемент .even в последующем .datagrid, а не на первый.

[3] делает сложным комбинировать это с тем, что следует. Заманчиво использовать .even:nth-child(3) или .even:nth-of-type(3), но это было бы ошибкой, потому что ни один из этих совпадений не подходит для .even, а затем берет третий. nth-child соответствует только элементам, которые являются и.evenи третий дочерний элемент их родителя (учитывая все элементы, а не только .even). nth-of-type делает то же самое, но только с учетом других элементов, имеющих один и тот же тег. Если у вас есть другие элементы не .even с тем же именем тега, это будет неправильно.

Иногда вы слышите разговоры о добавлении селектора (аналогично :eq, предоставленному jQuery), чтобы делать то, о чем вы говорите, но проблема (как я понимаю) заключается в том, что это потребует фундаментального изменения того, как механизмы выбора селектора процессов (справа налево). (Там же проблема, что JQuery невероятно широко используется, и использует 0 как индекс первого элемента, в то время как CSS использует 1 в подобных ситуациях. Таким образом, CSS придется использовать что-то другое, чем :eq   — возможно :index?   —, чтобы избежать путаницы.)

+1

Я бы добавил +1 для каждого абзаца, если бы мог :) – BoltClock

+0

Две вещи я задаю вопрос о вашем ответе. Во-первых, как я понимаю, 'querySelector ('. Datagrid')' получает только элемент _first_ '.datagrid', тогда как ваш объединенный' querySelectorAll ('. Datagrid .even') 'будет вытаскивать элементы _all_' .datagrid'. Во-вторых, если есть элементы _nested_ '.even' (поэтому' .even' является родительским для других элементов '.even'), будет ли версия OP и ваша комбинированная версия возвращать эти элементы _ в том же порядке_, что' [3] элемент был фактически одинаковым для обоих наборов возвращаемых значений? – ScottS

+1

@ScottS: Как ни странно, я, похоже, не получил уведомление о вашем комментарии. Отличные наблюдения. Совершенно верно, что вышеизложенное рассмотрит элементы '.even' не более чем в первом' .datagrid', я обновил ответ, чтобы объяснить это. Однако порядок совпадающих элементов '.even' не изменится; и код OP, и выше будут содержать элементы '.even' в порядке документа, вложенные или нет. Но вышеизложенное также ведет себя по-разному, если есть несколько элементов '.datagrid', и у первого нет четырех элементов' .even', поэтому я снова отметил это. Благодаря! –

0

Практически все, что вы можете сделать с помощью селектора css, вы можете сделать с помощью querySelector(), поэтому, если вы знаете свои селектора css, вы должны быть в порядке.

«Передача аргумента строки в querySelector должна следовать синтаксису CSS» - извлечь из API.