首页 文章

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

提问于
浏览
389

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

Peter    | male    | 34
Susanne  | female  | 12

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

15 回答

  • 93

    如果我正确读了the specification,没有 .

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

  • 4

    使用jQuery:

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

    看起来他们正在考虑CSS3规范 but it didn't make the cut .

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

  • 138

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

    HTML:

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

    CSS:

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

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

    • 元素的文本内容实际上是该元素的子元素

    • 您无法直接定位文本内容

    • CSS不允许使用选择器提升

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

  • 292

    您可以将内容设置为数据属性,然后使用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());
      });
    });
    
  • 119

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

  • 2

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

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

  • 4

    由于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/

  • 4

    @ 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>;
    }
    
  • 0

    我同意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}}">
    
  • 2

    你也可以使用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用于更改颜色,可以使用vanilla JavaScript添加:

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

    虽然 <td> 的结束标记may be omitted这样做可能会导致它被视为非空 .

  • 21

    这里的大多数答案试图提供如何编写HTML代码以包含更多数据的替代方法,因为至少在CSS3中,您无法通过部分内部文本选择元素 . 但它可以完成后,你只需要添加一些vanilla 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>
    
  • 1

    如果您使用的是Chimp / Webdriver.io,则它们比CSS规范support a lot more CSS selectors .

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

    browser.click("a*=Bad Bear");
    
  • -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')
                }
            })
        })
    

相关问题