Ищу селектор CSS для следующей таблицы:Есть ли селектор CSS для элементов, содержащих определенный текст?
Peter | male | 34
Susanne | female | 12
Есть ли селектор, чтобы соответствовать всем TDs, содержащие «мужской»?
Ищу селектор CSS для следующей таблицы:Есть ли селектор CSS для элементов, содержащих определенный текст?
Peter | male | 34
Susanne | female | 12
Есть ли селектор, чтобы соответствовать всем TDs, содержащие «мужской»?
Если я правильно прочитал the specification, нет.
Вы можете сопоставить элемент, имя атрибута в элементе и значение именованного атрибута в элементе. Тем не менее, я ничего не вижу для сопоставления содержимого внутри элемента.
Существует один краевой регистр: ': empty'. –
Комментарий выше должен быть выбранным ответом! –
Является ли этот ответ по-прежнему актуальным сегодня (2016 год)? –
Я боюсь, что это невозможно, потому что контент не является атрибутом и не доступен через псевдокласс. Полный список селекторов CSS3 можно найти в the CSS3 specification.
Вы должны были бы добавить атрибут данных в строках, называемых data-gender
со значением male
или female
и использовать селектор атрибута:
HTML:
<td data-gender="male">...</td>
CSS:
td[data-gender="male"] { ... }
Умное решение. Спасибо –
Атрибуты данных не используются как JS-крючки или селектор CSS - для этого предназначены классы. Из спецификации: 'Атрибуты пользовательских данных предназначены для хранения конфиденциальных данных на странице или приложении, для которых нет более подходящих атрибутов или элементов.' Ссылка на спецификацию: [ссылка] (http: // www .w3.org/html/wg/drafts/html/master/dom.html # embedding-custom-non-visible-data-with-the-data - * - attributes) –
@ Иван Дюрст, я искренне не согласен, как JS перехватчики или селектор CSS соответствуют определению данных, закрытым для страницы или приложения, и в настоящее время для гендерного пола не существует более подходящей html-семантики. Чем больше ответственности мы кладем на атрибут класса, тем дальше мы получаем от семантического html, поэтому я все для начала использования увеличенных метаданных, доступных нам в html5. – DannyMeister
Похоже, они думали об этом для спецификации CSS3 , но он не делал разреза.
:contains()
селектор CSS3 http://www.w3.org/TR/css3-selectors/#content-selectors
Последнее доступное определение': contains() 'можно найти здесь [http://www.w3.org/TR/2001/CR-css3-selectors-20011113/#content-selectors). – BoltClock
'Похоже, что они думали об этом для спецификации CSS3, но не сделали разреза. И по уважительной причине это нарушило бы всю предпосылку разделения стиля, содержания, структуры и поведения. – Synetech
@Synetech. Это может фактически помочь отделить стиль от контента, так как это означает, что контент не должен знать о его клиенте, который будет считаться важным для базового стиля. Прямо сейчас наш html-контент обычно тесно связан с css, включая классы, которые, как мы знаем, заботятся о стилистах. Они уже переходят к тому, чтобы позволить CSS на контенте, о чем свидетельствуют селекторы значений атрибутов в CSS3. – DannyMeister
Использование JQuery:
$('td:contains("male")')
Заканчивается необходимость в этом противоположном: jQuery (element) .not (": contains ('string')") – Jazzy
За исключением того, что это не CSS, это JavaScript. – Synetech
Согласен - вот почему мой ответ сказал, что я использую jQuery, а не CSS. Но эта часть моего ответа была отредактирована. =) – moettinger
Существует на самом деле очень концептуальная основа, почему это не было реализовано. Это сочетание в основном 3-х аспектах:
Эти 3 вместе означают, что к тому моменту, когда у вас есть текстовое содержимое, вы не сможете вернуться к содержащемуся элементу, и вы не можете стилизовать настоящий текст. Это, вероятно, значимо, поскольку спуск только позволяет синхронное отслеживание контекста и синтаксический анализ SAX. Восходящие или другие селекторы с участием других осей вносят потребность в более сложных обходах или подобных решениях, что значительно усложнит применение CSS в DOM.
Это правда. Для этого нужен XPath. Если вы можете выполнить селектор в JS/jQuery или в библиотеке синтаксического анализа (в отличие от CSS-only), тогда можно будет использовать функцию 'text()' XPath. –
Мне это оправдания. css - один из худших языков, с которыми я встречался. Используя? + @ #> И пространство (для крика вслух!), Поскольку ключевые слова для основной логики так восходят к 1980-м годам.По крайней мере, они могли бы использовать существующий ужасный контр-интуитивный язык-селектор, такой как регулярное выражение или xpath, они равномерно плохи, но по крайней мере вам не нужно было бы изучать другой. Лучшее, что они могли сделать, это использовать порт js, как для селекторов, свойств и значений. По крайней мере, таким образом, вы могли бы центрировать элемент в своем контейнере, когда речь идет о боковом элементе, например. – oriadam
Для тех, кто хочет сделать 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<IWebElement>)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";
}
Это javascript, как это связано с вопросом? – rubo77
Как вы не можете выбрать по контенту в css, вам нужно будет использовать js для этого. Хотя вы правы, когда указываете, что это не css, использование атрибута данных не выбирается по контенту. Мы можем только догадываться, почему читатель хочет выбрать ячейки по контенту, какой доступ у нее к html, сколько совпадений, насколько большой стол и т. Д. И т. Д. – user40521
Вы можете установить содержание в качестве атрибутов данных, а затем использовать 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());
});
});
Это очень удобный трюк для сгенерированной разметки – Whelkaholism
. text() 'и' .textContent' довольно тяжелые, старайтесь избегать их в длинных списках или больших текстах, когда это возможно. '.html()' и '.innerHTML' бывают быстрыми. – oriadam
@ ответ Вояджера об использовании data-*
атрибута (например, data-gender="female|male"
является наиболее эффективным и соответствует стандартам подхода как в 2017 году:
[data-gender='male'] {background-color: #000; color: #ccc;}
Довольно много больше голов может быть достигнуты, поскольку есть некоторые хотя и ограниченные селекторы ориентированных вокруг текста. ::first-letter - это pseudo-element, который может применять ограниченный стиль к первой букве элемента. Существует также псевдоэлемент ::first-line, кроме того, что, очевидно, выбор первой строки элемента (например, параграф) также подразумевает, что очевидно, что CSS можно использовать для расширения этой существующей возможности для стилизации определенных аспектов текстового элемента.
Пока такая пропаганда не удастся и реализована следующая лучшая вещь, которую я мог бы предложить, когда это применимо, чтобы explode
/split
слов с использованием космического deliminator, выход каждого отдельного слова внутри span
элемента, а затем, если слово/стайлинг цель предсказуем использование в сочетании с :nth selectors:
$p = explode(' ',$words);
foreach ($p as $key1 => $value1)
{
echo '<span>'.$value1.'</span>;
}
Else если не предсказуемы, опять же, использовать ответ Вояджера об использовании data-*
атрибута. Пример использования PHP:
$p = explode(' ',$words);
foreach ($p as $key1 => $value1)
{
echo '<span data-word="'.$value1.'">'.$value1.'</span>;
}
Я согласен 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}}">
Большинство ответов здесь пытаются предложить альтернативу, как писать HTML чтобы включить больше данных, потому что по крайней мере до CSS3 вы не можете выбрать элемент путем частичного внутреннего текста. Но это может быть сделано, вам просто нужно добавить немного ванили JavaScript, обратите внимание, поскольку женщина содержит также мужчина будет выбран:
cells = document.querySelectorAll('td');
\t console.log(cells);
[].forEach.call(cells, function (el) {
\t if(el.innerText.indexOf("male") !== -1){
\t //el.click(); click or any other option
\t console.log(el)
\t }
});
<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>
Если вы используете Chimp/Webdriver.io, они support a lot more CSS selectors, чем спецификация CSS.
Это, к примеру, нажмите на первый якорь, который содержит слова «Bad медведь»:
browser.click("a*=Bad Bear");
У меня была такая же проблема с некоторыми плохо сформированной HTML. Все данные, содержащиеся в ярлыках <td>
, без дополнительной идентифицирующей информации.
Предостережение: это работает только потому, что в последующем тексте <td>
всегда содержалось «значение» для предыдущего текста <td>
.
Я искал адреса для всех станций CTA в Чикаго. У меня была база данных с номером станции, поэтому мне удалось создать хеш, связывающий номер станции с адресом с приведенным ниже кодом.
td_hash = {}
filename = Rails.root + "cta_geojson.geojson"
page = open(filename)
parsed_json = JSON.parse(page.read)
q = parsed_json['features'].map {|e| e['properties']['description'] } #description was a string of badly formed HTML
q.each do |station|
doc = Nokogiri::HTML(station)
td = doc.css("td") #collect the td's
s_address = 0 #address selector. This goes to 1 when the <td> text is "ADDRESS" becase we know the address is in the next <td>
s_gtfs = 0 #gtfs selector. This goes to 1 when the <td> text is "GTFS" because we know the cta number is in the next <td>
key = ''
value = ''
td.each do |td|
if s_address == 1
value = td.text
s_address = 0
end
if s_gtfs == 1
key = td.text
td_hash.store(key,value)
s_gtfs = 0
end
if td.text == "ADDRESS"
s_address = s_address + 1
end
if td.text == "GTFS"
s_gtfs = s_gtfs + 1
end
end
end
Проблема в том, что это было бы очень сложно реализовать по-настоящему. – Ms2ger
Теперь я использую jQuery. Он работает отлично. – jantimon
Селектор XPath может сделать это с помощью метода .text() (если вы не хотите использовать JavaScript-исполнитель). – djangofan