it-swarm.com.ru

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

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

Peter    | male    | 34
Susanne  | female  | 12

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

376
jantimon

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

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

286
Dean J

Используя jQuery: 

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

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

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

119
Jeff Beaman

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

HTML:

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

CSS:

td[data-gender="male"] { ... }
92
Esteban Küber

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

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

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

59
Matt Whipple

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

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

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

Для тех, кто хочет делать выделение текста в 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
Matas Vaitkevicius

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

4
Edwin V.

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

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

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

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

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

Я согласен атрибут данных (ответ voyager) таков, как он должен обрабатываться, НО, правила 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
DJDaveMark

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

A ZeroWidthSpace используется для изменения цвета и может быть добавлен с помощью Vanilla JavaScript:

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

Хотя конечный тег <td>s может быть опущен это может привести к тому, что он будет рассматриваться как непустой.

1
Josh Habdas

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

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

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

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