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

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

Peter    | male    | 34
Susanne  | female  | 12

Есть ли какой-либо селектор для соответствия всем TD, содержащим "male"?

Ответ 1

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

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

Ответ 2

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

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

Ответ 4

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

HTML:

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

CSS

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

Ответ 5

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

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

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

Ответ 6

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

/* 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>

Ответ 7

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

Ответ 8

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

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

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

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

Ответ 10

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

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

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

До тех пор, пока такая защита не удастся и не будет реализована, следующая лучшая вещь, которую я мог бы предложить, когда это применимо, - это слова explode/split, используя разделитель пространства, выводить каждое отдельное слово внутри элемента span, а затем, если слово /styling target является предсказуемым использованием в сочетании с : 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>;
}

Ответ 11

Я согласен, что атрибут data (voyager answer) - это то, как его следует обрабатывать, НО, правила 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}}">

Ответ 12

Большинство ответов здесь предлагают альтернативу тому, как писать 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>

Ответ 14

Вы также можете использовать 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">&#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>

Ответ 15

Выполнение небольших фильтров:

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