3

我使用webdriver並經常使用css選擇器,並想知道是否可以減少遍歷每個級別的代碼量。以下是訪問元素的JavaScript代碼,並且在我的代碼中將出現類似的java代碼。如何組合css選擇器

在下面的例子中,我用3個css選擇器來遍歷3個級別,我可以將它們組合在一起或至少簡化。

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

[Selenium中的CSS選擇器](http://sauceio.com/index.php/2010/01/selenium-totw-css-selectors-in-selenium-demystified/)有幫助? – screenmutt

回答

7

您可以使用descendantchild選擇(技術上「組合子」)的第一部分結合起來:

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

...但它會使瀏覽器的工作有點困難比你的代碼做,因爲代碼的第一部分(document.querySelector('.datagrid'))將在找到匹配元素的第一個時停止查找,然後僅在該範圍內查找.even元素。以上看起來全部.even元素有.datagrid祖先。所以它可能需要搜索更多的文檔。大部分時間無關緊要,但值得指出。以上還假定在第一個.datagrid中至少有四個.even元素。如果沒有,你的代碼將拋出一個錯誤(因爲試圖調用.querySelectorAll[3],這將是null的),而上面的代碼可能拋出一個錯誤(如果有不是四在頁面上),或者可能在後續.datagrid而不是第一個中引用.even元素。

[3]使它與後面的結合起來很難。使用.even:nth-child(3).even:nth-of-type(3)是很誘人的,但這是一個錯誤,因爲這些計數都不匹配.even,然後取第三個。只有nth-child比賽是元素都.even他們的父母的第三個孩子元素(考慮所有元素,而不僅僅是那些.even)。 nth-of-type做同樣的事情,但只考慮具有相同標記的其他元素。如果您有其他非.even元素具有相同的標籤名稱,則這將是錯誤的。

有時您會聽到有關添加選擇器的說法(類似於jQuery提供的:eq)來執行您正在討論的內容,但問題(據我瞭解)是需要根本改變選擇器引擎進程選擇器(從右到左)。 (另外還有一個問題,即jQuery是極其廣泛的應用,並使用0作爲第一個元素的索引,而CSS在類似情況下使用1。所以CSS將不得不使用其他的東西比:eq   —也許:index?  —以避免混淆。 )

+1

如果可以的話,我會爲每個段落+1這個問題:) – BoltClock

+0

我對你的回答提出了兩件事。首先,據我所知,'querySelector('。datagrid')'只能得到_first_'.datagrid'元素,而你的組合'querySelectorAll('.dggrid .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中提取。