Есть ли селектор CSS для элементов, содержащих определенный текст?

Я ищу селектор CSS для следующей таблицы:

Peter | male | 34 Susanne | female | 12 

Есть ли какой-либо селектор для соответствия всем ТД, содержащим «мужчин»?

Если я правильно прочитал спецификацию , нет.

Вы можете сопоставлять элемент, имя атрибута в элементе и значение именованного атрибута в элементе. Тем не менее, я ничего не вижу для сопоставления содержимого внутри элемента.

Использование jQuery:

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

Похоже, они думали об этом для спецификации CSS3, но не делали разреза .

:contains() селектор CSS3 http://www.w3.org/TR/css3-selectors/#content-selectors

Вам нужно будет добавить атрибут данных в строки с именем data-gender с male или female значением и использовать селектор атрибутов:

HTML:

 ... 

CSS:

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

На самом деле существует очень концептуальная основа того, почему это не было реализовано. Это комбинация в основном трех аспектов:

  1. Текстовое содержимое элемента фактически является дочерним элементом этого элемента
  2. Вы не можете напрямую настроить таргетинг на текстовый контент
  3. CSS не допускает вознесения с помощью селекторов

Эти 3 вместе означают, что к моменту, когда у вас есть текстовое содержимое, вы не сможете вернуться к содержащемуся элементу, и вы не можете стилизовать настоящий текст. Это, вероятно, значимо, поскольку спуск только позволяет синхронное отслеживание контекста и синтаксический анализ SAX. Восходящие или другие селекторы с участием других осей вносят потребность в более сложных обходах или подобных решениях, что значительно усложнит применение CSS в DOM.

Вы можете установить контент как атрибут данных, а затем использовать селектора атрибутов

 /* 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; } 
 
Peter male 34
Susanne female 14

Для тех, кто хочет сделать Selenium CSS text selections, этот скрипт может пригодиться.

Трюк состоит в том, чтобы выбрать родителя элемента, который вы ищете, а затем выполнить поиск для ребенка, у которого есть текст:

 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)element)[0]; } 

Это вернет первый элемент, если его больше одного, поскольку в моем случае это всегда один элемент.

Поскольку 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/

Я боюсь, что это невозможно, потому что контент не является атрибутом и не доступен через псевдоclass. Полный список селекторов CSS3 можно найти в спецификации CSS3 .

Ответ @ voyager об использовании атрибута data-* (например, data-gender="female|male" является наиболее эффективным и стандартизованным подходом к 2017 году:

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

Практически большинство целей может быть достигнуто, поскольку есть некоторые, хотя и ограниченные селектора, ориентированные вокруг текста. Первая буква – это псевдоэлемент, который может применять ограниченный стиль к первой букве элемента. Существует также псевдоэлемент :: first-line, кроме того, что, очевидно, выбор первой строки элемента (например, абзаца) также подразумевает, что очевидно, что CSS можно использовать для расширения этой существующей возможности для стилизации определенных аспектов textNode ,

До тех пор, пока такая защита не будет успешной и не будет реализована, следующая лучшая вещь, которую я мог бы предложить, когда это применимо, состоит в том, чтобы explode / split слова, используя split пространства, выводить каждое отдельное слово внутри элемента span а затем, если цель слова / стиля предсказуема, : nth селекторов :

 $p = explode(' ',$words); foreach ($p as $key1 => $value1) { echo ''.$value1.'; } 

Иначе, если не предсказуемо , снова используйте ответ voyager об использовании атрибута data-* . Пример использования PHP:

 $p = explode(' ',$words); foreach ($p as $key1 => $value1) { echo ''.$value1.'; } 

Я согласен, что атрибут data (ответ voyager) заключается в том, как его следует обрабатывать, НО, правила CSS, такие как:

 td.male { color: blue; } td.female { color: pink; } 

часто может быть намного проще настроить, особенно с клиентскими библиотеками, такими как angularjs, которые могут быть такими же простыми, как:

  

Просто убедитесь, что содержание – всего лишь одно слово! Или вы даже можете сопоставить различные имена classов CSS с помощью:

  

Для полноты, вот подход атрибутов данных:

  

Большинство ответов здесь предлагают альтернативу тому, как писать 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) } }); 
  
Peter male 34
Susanne female 14

Если вы используете Chimp / Webdriver.io , они поддерживают намного больше селекторов CSS, чем спецификация CSS.

Это, например, нажмет на первый якорь, содержащий слова «Bad bear»:

 browser.click("a*=Bad Bear"); 
Interesting Posts
Давайте будем гением компьютера.