我正在寻找下表的CSS选择器:
Peter | male | 34
Susanne | female | 12
是否有任何选择器来匹配所有包含“ male”的TD?
$x
回答这个问题。对于最初的问题,$x("//td[text()='male']")
这个窍门
我正在寻找下表的CSS选择器:
Peter | male | 34
Susanne | female | 12
是否有任何选择器来匹配所有包含“ male”的TD?
$x
回答这个问题。对于最初的问题,$x("//td[text()='male']")
这个窍门
Answers:
如果我正确阅读了说明书,否。
您可以匹配元素,元素中属性的名称以及元素中命名属性的值。不过,我看不到任何与内容匹配的元素。
:empty
。
使用jQuery:
$('td:contains("male")')
看起来他们在考虑CSS3规范的问题,但是并没有成功。
:contains()
CSS3选择器http://www.w3.org/TR/css3-selectors/#content-selectors
Looks like they were thinking about it for the CSS3 spec but it didn't make the cut.
并且有充分的理由,它将违反将样式,内容,结构和行为分开的整个前提。
您必须将数据属性添加到data-gender
用male
或female
值调用的行中,并使用属性选择器:
HTML:
<td data-gender="male">...</td>
CSS:
td[data-gender="male"] { ... }
male
或female
呢?class
不能保证充斥其他类,它们的顺序的事实,可能与其他类名发生冲突等,使得class
这种情况变得更糟。专用data-*
属性会将您的数据与所有内容隔离开来,并使使用属性选择器对其进行部分匹配等操作变得更加容易。
实际上,有一个非常概念性的基础来说明为什么尚未实现这一点。它基本上是三个方面的组合:
这3个共同意味着,当您拥有文本内容时,您将无法返回到包含元素,也无法为当前文本设置样式。这可能很重要,因为降序仅允许上下文的单一跟踪和SAX样式解析。升序或涉及其他轴的其他选择器引入了对更复杂的遍历或类似解决方案的需求,这将使CSS在DOM中的应用极大地复杂化。
text()
功能。
:contains(<sub-selector>)
选择一个包含其他特定元素的元素。就像div:contains(div[id~="bannerAd"])
摆脱广告和它的容器。
您可以将内容设置为数据属性,然后使用属性选择器,如下所示:
/* Select every cell containing 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-conten="Susanne">Susanne</td>
<td data-content="female">female</td>
<td data-content="14">14</td>
</tr>
</table>
您还可以使用jQuery轻松设置数据内容属性:
$(function(){
$("td").each(function(){
var $this = $(this);
$this.attr("data-content", $this.text());
});
});
.text()
和.textContent
是相当沉重的,尽量避免他们在长的列表或大的文本可能的情况下。.html()
而且.innerHTML
很快。
$("td:contains(male)")
contenteditable='true'
-我的情况),则data-content
在呈现页面之前设置属性值是不够的。它必须不断更新。这是我使用的:<td onkeypress="event.target.setAttribute('data-content', event.target.textContent);">
由于CSS缺少此功能,因此您将不得不使用JavaScript来按内容设置单元格样式。例如,使用XPath contains
:
var elms = document.evaluate( "//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";
}
对于那些希望选择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];
}
如果有多个元素,它将返回第一个元素,因为在我的情况下,它始终是一个元素。
TD:contains('male')
是Selenium,则可以使用:imho仅在无法更新源代码以添加类时才使用。例如,如果您正在测试遗留代码,或者您的公司不允许您与开发人员交谈(eurgh!),因为您的测试将很脆弱,并且如果有人稍后将文本masculine
更改为或更改语言,则测试将失败。SauceLabs文档显示了contains
此处的使用(ucelabs.com/resources/articles/selenium-tips-css-selectors)+ cc @matas vaitkevicius我错过了什么吗?
我同意数据属性(旅行者的回答)是应该如何处理,但应遵循以下CSS规则:
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}}">
@voyager关于使用data-*
属性的答案(例如data-gender="female|male"
,截至2017年,这是最有效且符合标准的方法:
[data-gender='male'] {background-color: #000; color: #ccc;}
尽管有一些围绕文本的有限选择器,但几乎可以实现大多数目标。所述::第一字母是一个伪元件可应用于有限的造型到元件的第一个字母。还有一个:: first-line除了明显地选择元素(例如段落)的第一行之外,伪元素,这也意味着很明显,可以使用CSS来扩展此现有功能来为textNode的特定方面设置样式。
在这样的倡导获得成功并实施之前,我可能建议的下一件最好的事情是使用空格分隔符explode
/ split
来输出/ 单词,在span
元素内输出每个单词,然后将该单词/样式目标与#nth选择器组合使用是可预测的:
$p = explode(' ',$words);
foreach ($p as $key1 => $value1)
{
echo '<span>'.$value1.'</span>;
}
否则,即使无法预料,还是要使用航海家关于使用data-*
属性的答案。使用PHP的示例:
$p = explode(' ',$words);
foreach ($p as $key1 => $value1)
{
echo '<span data-word="'.$value1.'">'.$value1.'</span>;
}
如果您使用的是Chimp / Webdriver.io,那么它们比CSS规范支持更多的CSS选择器。
例如,这将单击包含单词“ Bad bear”的第一个锚点:
browser.click("a*=Bad Bear");
这里的大多数答案都试图提供一种替代方法,以替代编写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>
<table>
<tr>
<td data-content="Peter">Peter</td>
<td data-content="male">male</td>
<td data-content="34">34</td>
</tr>
<tr>
<td data-conten="Susanne">Susanne</td>
<td data-content="female">female</td>
<td data-content="14">14</td>
</tr>
</table>
你也可以使用content
与attr()
那些和样式表格单元格::not
:empty
th::after { content: attr(data-value) }
td::after { content: attr(data-value) }
td[data-value]:not(:empty) {
color: fuchsia;
}
<table>
<tr>
<th data-value="Peter"></th>
<td data-value="male">​</td>
<td data-value="34"></td>
</tr>
<tr>
<th data-value="Susanne"></th>
<td data-value="female"></td>
<td data-value="12"></td>
</tr>
<tr>
<th data-value="Lucas"></th>
<td data-value="male">​</td>
<td data-value="41"></td>
</tr>
</table>
A ZeroWidthSpace
用于更改颜色,可以使用原始JavaScript添加:
const hombres = document.querySelectorAll('td[data-value="male"]');
hombres.forEach(hombre => hombre.innerHTML = '​');
如果您不是自己创建DOM(例如在用户脚本中),则可以使用纯JS执行以下操作:
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>
控制台输出
text: <td> Peter
text: <td> male
text: <td> 34
text: <td> Susanne
text: <td> female
text: <td> 12
male: <td text="male"> male
像这样做小的过滤器小部件:
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')
}
})
})
该问题的语法类似于Robot Framework语法。在这种情况下,尽管没有可用于包含的css选择器,但可以使用SeleniumLibrary关键字来代替。该等到元素包含。
例:
Wait Until Element Contains | ${element} | ${contains}
Wait Until Element Contains | td | male