我正在為下表尋找一個CSS選擇器:
Peter | male | 34
Susanne | female | 12
有沒有選擇器匹配所有包含“男性”的TDs?
如果我沒看錯說明書的話,沒有。
您可以匹配元素、元素中屬性的名稱以及元素中命名屬性的值。但是,我看不到元素內匹配內容的任何東西。
看起來他們正在為CSS3規(guī)范考慮這個問題,但是沒有成功。
:包含()CSS3選擇器http://www.w3.org/TR/css3-selectors/#content-selectors
使用jQuery:
$('td:contains("male")')
您必須向名為data-gender的行添加一個帶有男性或女性值的數據屬性,并使用屬性選擇器:
HTML:
<td data-gender="male">...</td>
CSS:
td[data-gender="male"] { ... }
這實際上是沒有實現的一個非常概念性的基礎。它基本上是三個方面的結合:
元素的文本內容實際上是該元素的子元素 您不能直接定位文本內容 CSS不允許用選擇器提升 這三者合在一起意味著當您擁有文本內容時,您無法返回到包含它的元素,也無法對當前文本進行樣式化。這可能很重要,因為降序只允許對上下文和SAX樣式解析進行單一跟蹤。涉及其他軸的升序或其他選擇器引入了對更復雜的遍歷或類似解決方案的需求,這將使CSS在DOM中的應用變得非常復雜。
您可以將內容設置為數據屬性,然后使用屬性選擇器,如下所示:
/* Select every cell matching the word "male" */
td[data-content="male"] {
color: red;
}
/* Select every cell starting on "p" case insensitive */
td[data-content^="p" i] {
color: blue;
}
/* Select every cell containing "4" */
td[data-content*="4"] {
color: green;
}
<table>
<tr>
<td data-content="Peter">Peter</td>
<td data-content="male">male</td>
<td data-content="34">34</td>
</tr>
<tr>
<td data-content="Susanne">Susanne</td>
<td data-content="female">female</td>
<td data-content="14">14</td>
</tr>
</table>
由于CSS缺乏這一特性,你將不得不使用JavaScript來根據內容設置單元格的樣式。例如,XPath的包含:
var elms = document.evaluate( "http://td[contains(., 'male')]", node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null )
然后像這樣使用結果:
for ( var i=0 ; i < elms.snapshotLength; i++ ){
elms.snapshotItem(i).style.background = "pink";
}
https://jsfiddle.net/gaby_de_wilde/o7bka7Ls/9/
這實際上與OPs問題無關,但它解決了一個類似的問題:
:有()
示例:以下選擇器僅匹配直接包含子元素的元素:
a:has(> img)
參考資料:
https://developer.mozilla.org/en-US/docs/Web/CSS/:has
https://caniuse.com/?搜索=有
恐怕這是不可能的,因為內容沒有屬性,也不能通過偽類訪問。CSS3選擇器的完整列表可以在CSS3規(guī)范中找到。
對于那些希望選擇Selenium CSS文本的人來說,這個腳本可能會有一些用處。
訣竅是選擇您要查找的元素的父元素,然后搜索包含該文本的子元素:
public static IWebElement FindByText(this IWebDriver driver, string text)
{
var list = driver.FindElement(By.CssSelector("#RiskAddressList"));
var element = ((IJavaScriptExecutor)driver).ExecuteScript(string.Format(" var x = $(arguments[0]).find(\":contains('{0}')\"); return x;", text), list);
return ((System.Collections.ObjectModel.ReadOnlyCollection<IWebElement>)element)[0];
}
如果有多個元素,這將返回第一個元素,因為在我的例子中,它總是一個元素。
如果您沒有自己創(chuàng)建DOM(例如,在一個用戶腳本中),您可以使用純JS執(zhí)行以下操作:
for ( td of document.querySelectorAll('td') ) {
console.debug("text:", td, td.innerText)
td.setAttribute('text', td.innerText)
}
for ( td of document.querySelectorAll('td[text="male"]') )
console.debug("male:", td, td.innerText)
<table>
<tr>
<td>Peter</td>
<td>male</td>
<td>34</td>
</tr>
<tr>
<td>Susanne</td>
<td>female</td>
<td>12</td>
</tr>
</table>
到處都是優(yōu)秀的答案,但是我想我可以添加一些在實際場景中對我有用的東西:利用CSS的aria-label屬性。
對于不知道的讀者:aria-label是一個屬性,它與其他類似的屬性一起使用,讓屏幕閱讀器知道某個東西是什么,以防有視覺障礙的人使用您的網站。許多網站將這些屬性添加到包含圖像或文本的元素中,作為& quot描述符& quot。
這使得它高度特定于網站,但是如果您的元素包含它,那么使用屬性的內容來選擇該元素是相當簡單的:
HTML:
<td aria-label="male">Male</td>
<td aria-label="female">Female</td>
CSS:
td[aria-label="male"] {
outline: 1px dotted green;
}
從技術上講,這與使用數據屬性解決方案是一回事,但如果您不是網站的作者,這也適用于您,而且這不是專門為支持這種用例而設計的一些過時的解決方案;它本身是相當普遍的。它的一個缺點是,真的不能保證您想要的元素會有這個屬性。
這里的大多數答案試圖提供如何編寫HTML代碼以包含更多數據的替代方法,因為至少在CSS3之前,您不能通過部分內部文本選擇元素。但這是可以做到的,你只需要添加一點普通的JavaScript,注意因為女性也包含男性,所以它將被選中:
cells = document.querySelectorAll('td');
console.log(cells);
[].forEach.call(cells, function (el) {
if(el.innerText.indexOf("male") !== -1){
//el.click(); click or any other option
console.log(el)
}
});
<table>
<tr>
<td>Peter</td>
<td>male</td>
<td>34</td>
</tr>
<tr>
<td>Susanne</td>
<td>female</td>
<td>14</td>
</tr>
</table>
我同意數據屬性(voyager的答案)是應該如何處理的,但是,CSS規(guī)則像:
td.male { color: blue; }
td.female { color: pink; }
通常更容易設置,尤其是像angularjs這樣的客戶端庫,可以簡單到:
<td class="{{person.gender}}">
只要保證內容只有一個字就好!或者,您甚至可以使用以下命令映射到不同的CSS類名:
<td ng-class="{'masculine': person.isMale(), 'feminine': person.isFemale()}">
為了完整起見,下面是數據屬性方法:
<td data-gender="{{person.gender}}">
如果你使用的是Chimp / Webdriver.io,它們支持的CSS選擇器比CSS規(guī)范多得多。
例如,這將點擊包含單詞“Bad bear”的第一個錨:
browser.click("a*=Bad Bear");
@voyager關于使用data-*屬性的回答(例如data-gender="female|male "是截至2017年最有效且符合標準的方法:
[data-gender='male'] {background-color: #000; color: #ccc;}
幾乎大多數目標都可以實現,因為有一些面向文本的選擇器,盡管有限。::first-letter是一個偽元素,它可以對元素的第一個字母應用有限的樣式。除了選擇元素(如段落)的第一行之外,還有一個::first-line偽元素,這也意味著CSS顯然可以用來擴展這一現有功能,以樣式化textNode的特定方面。
在這種倡導成功并得以實施之前,我建議的下一個最佳方案是使用空格分隔符分解/拆分單詞,輸出span元素中的每個單詞,然后如果單詞/樣式目標是可預測的,則使用以下選項的組合:
$p = explode(' ',$words);
foreach ($p as $key1 => $value1)
{
echo '<span>'.$value1.'</span>;
}
否則,如果不可預測,再次使用voyager關于使用data-*屬性的回答。使用PHP的一個例子:
$p = explode(' ',$words);
foreach ($p as $key1 => $value1)
{
echo '<span data-word="'.$value1.'">'.$value1.'</span>;
}
您可以將內容轉移到單元格的一個屬性中,然后使用CSS復制它以用于顯示目的(不要重復您自己——其他類似的回答忽略了這一點)。 這利用了內容和屬性()
td[aria-label]::before {
content: attr(aria-label);
/*text-transform: capitalize; <-- possible */
}
td[aria-label="male"] {
color: fuchsia;
}
<table>
<tr>
<td aria-label="Peter"></td>
<td aria-label="male"></td>
<td aria-label="34"></td>
</tr>
<tr>
<td aria-label="Susanne"></td>
<td aria-label="female"></td>
<td aria-label="12"></td>
</tr>
<tr>
<td aria-label="Lucas"></td>
<td aria-label="male"></td>
<td aria-label="41"></td>
</tr>
</table>
如果您不想使用javascript或jquery,我發(fā)現屬性選項是您的最佳選擇。
例如,要用單詞ready設置所有表格單元格的樣式,請在HTML中這樣做:
<td status*="ready">Ready</td>
然后在css中:
td[status*="ready"] {
color: red;
}
如果您想要將樣式應用于您想要的內容。簡單的把戲。
td { border: 1px solid black; }
td:empty { background: lime; }
td:empty::after { content: "male"; }
<table>
<tr>
<td>Peter</td>
<td><!--male--></td>
<td>34</td>
</tr>
<tr>
<td>Susanne</td>
<td>female</td>
<td>14</td>
</tr>
</table>
像這樣做小的過濾器部件:
var searchField = document.querySelector('HOWEVER_YOU_MAY_FIND_IT')
var faqEntries = document.querySelectorAll('WRAPPING_ELEMENT .entry')
searchField.addEventListener('keyup', function (evt) {
var testValue = evt.target.value.toLocaleLowerCase();
var regExp = RegExp(testValue);
faqEntries.forEach(function (entry) {
var text = entry.textContent.toLocaleLowerCase();
entry.classList.remove('show', 'hide');
if (regExp.test(text)) {
entry.classList.add('show')
} else {
entry.classList.add('hide')
}
})
})
這個問題的語法看起來像機器人框架語法。 在這種情況下,雖然沒有可以用于contains的css選擇器,但是有一個可以使用的SeleniumLibrary關鍵字。 等待直到元素包含。
示例:
Wait Until Element Contains | ${element} | ${contains}
Wait Until Element Contains | td | male