Je recherche un sélecteur CSS pour le tableau suivant:
Peter | male | 34
Susanne | female | 12
Y at-il un sélecteur pour faire correspondre tous les TD contenant "mâle"?
Si je lis la spécification correctement, non.
Vous pouvez faire correspondre un élément, le nom d'un attribut dans l'élément et la valeur d'un attribut nommé dans un élément. Je ne vois cependant rien pour faire correspondre le contenu d'un élément.
Utilisation de jQuery:
$('td:contains("male")')
On dirait qu'ils y pensaient pour la spécification CSS3 mais cela n'a pas fait la différence.
:contains()
Sélecteur CSS3 http://www.w3.org/TR/css3-selectors/#content-selectors
Vous devez ajouter un attribut de données aux lignes appelé data-gender
avec une valeur male
ou female
et utiliser le sélecteur d'attribut:
HTML:
<td data-gender="male">...</td>
CSS:
td[data-gender="male"] { ... }
Il existe en fait une base très conceptuelle pour expliquer pourquoi cela n'a pas été mis en œuvre. C'est une combinaison de 3 aspects principaux:
Ces 3 ensemble signifient que lorsque vous avez le contenu du texte, vous ne pouvez plus remonter à l'élément qui le contient et vous ne pouvez pas styliser le texte actuel. Ceci est probablement significatif car décroissant ne permet qu'un suivi singulier du contexte et de l'analyse syntaxique de style SAX. Les sélecteurs ascendants ou autres impliquant d'autres axes impliquent le besoin de solutions de traversée plus complexes ou de solutions similaires qui compliqueraient grandement l'application de CSS au DOM.
Vous pouvez définir le contenu en tant qu'attribut de données, puis utiliser sélecteurs d'attributs , comme indiqué ici:
/* 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>
Vous pouvez également utiliser jQuery pour définir facilement les attributs de contenu de données:
$(function(){
$("td").each(function(){
var $this = $(this);
$this.attr("data-content", $this.text());
});
});
Comme CSS ne dispose pas de cette fonctionnalité, vous devrez utiliser javascript pour styliser les cellules en fonction du contenu. Par exemple, avec xpath contient
var elms = document.evaluate( "//td[contains(., 'male')]" ,node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null )
Ensuite, utilisez le résultat comme suit:
for ( var i=0 ; i < elms.snapshotLength; i++ ){
elms.snapshotItem(i).style.background = "pink";
}
Pour ceux qui cherchent à faire des sélections de texte Selenium CSS, ce script pourrait être utile.
L'astuce consiste à sélectionner le parent de l'élément que vous recherchez, puis à rechercher l'enfant qui contient le texte:
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];
}
Cela renverra le premier élément s'il y en a plus d'un puisqu'il s'agit toujours d'un élément, dans mon cas.
Je crains que cela ne soit pas possible, car le contenu n'est pas un attribut et n'est pas accessible via une pseudo-classe. La liste complète des sélecteurs CSS3 se trouve dans la spécification CSS3 .
Je suis d'accord l'attribut data (réponse du voyageur) est la façon dont il devrait être traité, MAIS, des règles CSS telles que
td.male { color: blue; }
td.female { color: pink; }
peut souvent être beaucoup plus facile à configurer, en particulier avec des bibliothèques côté client comme angularjs, qui pourraient être aussi simples que:
<td class="{{person.gender}}">
Assurez-vous simplement que le contenu n'est qu'un mot! Vous pouvez également mapper des noms de classes CSS différents avec:
<td ng-class="{'masculine': person.isMale(), 'feminine': person.isFemale()}">
Pour être complet, voici l'approche des attributs de données:
<td data-gender="{{person.gender}}">
Vous pouvez également utiliser content
avec attr()
et les cellules de table de style qui sont :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">​</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">​</td>
<td data-value="41"></td>
</tr>
</table>
Un ZeroWidthSpace
est utilisé pour modifier la couleur et peut être ajouté à l'aide de JavaScript Vanille:
const hombres = document.querySelectorAll('td[data-value="male"]');
hombres.forEach(hombre => hombre.innerHTML = '​');
Bien que la balise de fin <td>
s peut être omise cela peut entraîner son traitement comme non vide.
La syntaxe de cette question ressemble à la syntaxe Robot Framework. Dans ce cas, bien qu’il n’y ait pas de sélecteur css que vous puissiez utiliser pour les contenus, vous pouvez utiliser un mot-clé SeleniumLibrary. Le Attendre que l'élément contienne .
Exemple:
Wait Until Element Contains | ${element} | ${contains}
Wait Until Element Contains | td | male
La plupart des réponses ici tentent d’offrir une alternative à la façon d’écrire le code HTML pour inclure plus de données car au moins jusqu’à CSS3, vous ne pouvez pas sélectionner un élément avec un texte interne partiel. Mais cela peut être fait, il vous suffit d’ajouter un peu de JavaScript Vanille, remarquez que puisque la femme contient aussi un homme, il sera sélectionné:
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>
Si vous utilisez Chimp / Webdriver.io , ils prennent en charge beaucoup plus de sélecteurs CSS que la spécification CSS.
Ceci, par exemple, cliquera sur la première ancre contenant les mots "Mauvais ours":
browser.click("a*=Bad Bear");