是否有包含特定文本的元素的CSS选择器?

时间:2009-10-05 14:26:10

标签: css css-selectors

我正在寻找下表的CSS选择器:

Peter    | male    | 34
Susanne  | female  | 12

是否有任何选择器匹配所有包含“男性”的TD?

19 个答案:

答案 0 :(得分:299)

如果我正确阅读the specification,请不要。

您可以匹配元素,元素中属性的名称以及元素中命名属性的值。但是,我看不到元素中匹配内容的任何内容。

答案 1 :(得分:141)

使用jQuery:

$('td:contains("male")')

答案 2 :(得分:124)

看起来他们正在考虑CSS3规范,但它没有削减

:contains() CSS3选择器http://www.w3.org/TR/css3-selectors/#content-selectors

答案 3 :(得分:96)

您必须向名为data-gender的行添加数据属性,并使用malefemale值并使用属性选择器:

HTML:

<td data-gender="male">...</td>

CSS:

td[data-gender="male"] { ... }

答案 4 :(得分:60)

实际上有一个非常概念性的基础,为什么没有实施。它基本上是3个方面的组合:

  1. 元素的文本内容实际上是该元素的子元素
  2. 您无法直接定位文字内容
  3. CSS不允许使用选择器提升
  4. 这三个一起意味着当您拥有文本内容时,您无法升级回包含元素,并且您无法设置当前文本的样式。这可能很重要,因为降序只允许单一跟踪上下文和SAX样式解析。涉及其他轴的升序或其他选择器引入了对更复杂的遍历或类似解决方案的需求,这会使CSS的应用程序大大复杂化。

答案 5 :(得分:24)

您可以将内容设置为数据属性,然后使用attribute selectors,如下所示:

/* 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());
  });
});

答案 6 :(得分:5)

我担心这是不可能的,因为内容不是属性,也不能通过伪类访问。可以在the CSS3 specification中找到CSS3选择器的完整列表。

答案 7 :(得分:5)

由于CSS缺少此功能,您必须使用javascript按内容设置单元格样式。例如,xpath 包含

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";
}

https://jsfiddle.net/gaby_de_wilde/o7bka7Ls/9/

答案 8 :(得分:4)

对于那些希望进行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];
}

如果有多个元素,这将返回第一个元素,因为它总是一个元素,在我的情况下。

答案 9 :(得分:3)

截至 2021 年 1 月,有一些东西可以做到这一点。 :has() ... 只有一个问题:尚不支持任何浏览器

示例:以下选择器仅匹配直接包含子元素的元素:

a:has(> img)

参考文献:

https://developer.mozilla.org/en-US/docs/Web/CSS/:has

https://caniuse.com/?search=has

答案 10 :(得分:2)

我同意the data attribute(旅行者的答案)是应该如何处理的,但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}}">

答案 11 :(得分:2)

@ voyager关于使用data-*属性的答案(例如data-gender="female|male")是截至2017年最有效且符合标准的方法:

[data-gender='male'] {background-color: #000; color: #ccc;}

几乎所有目标都可以获得,因为有一些虽然有限的选择器围绕文本。 ::first-letterpseudo-element,可以将有限样式应用于元素的第一个字母。除了明显选择元素的第一行(例如段落)之外,还有一个::first-line伪元素,这也意味着可以使用CSS来扩展此现有功能以调整textNode的特定方面的样式。

直到这样的宣传成功实施之后,我可以建议的另一个最好的事情是在explode / split单词使用空格分隔符时,输出每个单词一个span元素,然后如果单词/样式目标是可预测的:nth selectors结合使用:

$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>;
}

答案 12 :(得分:1)

您还可以将contentattr():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">&#x0200B;</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">&#x0200B;</td>
    <td data-value="41"></td>
  </tr>
</table>

ZeroWidthSpace用于更改颜色,并且可以使用原始JavaScript添加:

const hombres = document.querySelectorAll('td[data-value="male"]');
hombres.forEach(hombre => hombre.innerHTML = '&#x0200B;');

尽管<td>的结束标记may be omitted这样做可能会导致将其视为非空。

答案 13 :(得分:1)

如果您不想使用javascript或jquery,我认为attribute选项是最好的选择。

例如,用单词ready为所有表格单元设置样式,在HTML中执行以下操作:

 <td status*="ready">Ready</td>

然后在CSS中:

td[status*="ready"] {
        color: red;
    }

答案 14 :(得分:0)

这里的大多数答案试图提供如何编写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>

答案 15 :(得分:0)

如果您使用的是Chimp / Webdriver.io,那么他们support a lot more CSS selectors比CSS规范要好。

例如,这将点击包含单词“Bad bear”的第一个锚:

browser.click("a*=Bad Bear");

答案 16 :(得分:0)

如果您自己(例如在用户脚本中)不创建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

答案 17 :(得分:-2)

像这样做小的过滤器小部件:

    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')
            }
        })
    })

答案 18 :(得分:-2)

此问题的语法类似于Robot Framework语法。 在这种情况下,尽管没有可用于包含的css选择器,但可以使用SeleniumLibrary关键字来代替。 Wait Until Element Contains

示例:

Wait Until Element Contains  | ${element} | ${contains}
Wait Until Element Contains  |  td | male