Esiste un selettore CSS per elementi contenenti determinati testi?

Sto cercando un selettore CSS per la seguente tabella:

Peter | male | 34 Susanne | female | 12 

C’è un selettore per abbinare tutti i TD contenenti “maschio”?

Se leggo correttamente le specifiche , no.

È ansible associare un elemento, il nome di un attributo nell’elemento e il valore di un attributo denominato in un elemento. Tuttavia, non vedo nulla per la corrispondenza del contenuto all’interno di un elemento.

Usando jQuery:

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

Sembra che ci stessero pensando per la specifica CSS3 ma non ha fatto il taglio .

:contains() selettore CSS3 http://www.w3.org/TR/css3-selectors/#content-selectors

Dovresti aggiungere un attributo di dati alle righe chiamate data-gender con un valore male o female e utilizzare il selettore dell’attributo:

HTML:

 ... 

CSS:

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

C’è in realtà una base molto concettuale per cui questo non è stato implementato. È una combinazione di fondamentalmente 3 aspetti:

  1. Il contenuto testuale di un elemento è effettivamente figlio di quell’elemento
  2. Non puoi indirizzare direttamente il contenuto del testo
  3. I CSS non consentono l’ascensione con i selettori

Questi 3 insieme significano che quando si ha il contenuto del testo non è ansible risalire all’elemento contenitore e non è ansible applicare lo stile al testo presente. Ciò è probabilmente significativo poiché la discesa consente solo un monitoraggio singolare del contesto e l’analisi dello stile SAX. Ascendente o altri selettori che coinvolgono altri assi introducono la necessità di soluzioni trasversali più complesse o simili che complicherebbero notevolmente l’applicazione del CSS al DOM.

È ansible impostare il contenuto come attributo dei dati e quindi utilizzare i selettori di attributo

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

Per coloro che stanno cercando di fare selezioni di testo CSS Selenium, questo script potrebbe essere di qualche utilità.

Il trucco è selezionare il genitore dell’elemento che stai cercando, quindi cercare il bambino con il testo:

 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]; } 

Questo restituirà il primo elemento se ce n’è più di uno poiché è sempre un elemento, nel mio caso.

Siccome il CSS non ha questa caratteristica, dovrai usare javascript per creare lo stile delle celle per contenuto. Ad esempio con xpath contiene

 var elms = document.evaluate( "//td[contains(., 'male')]" ,node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null ) 

Quindi usa il risultato in questo modo:

 for ( var i=0 ; i < elms.snapshotLength; i++ ){ elms.snapshotItem(i).style.background = "pink"; } 

https://jsfiddle.net/gaby_de_wilde/o7bka7Ls/9/

Temo che questo non sia ansible, perché il contenuto non è un attributo né è accessibile tramite una pseudo class. L’elenco completo dei selettori CSS3 può essere trovato nella specifica CSS3 .

La risposta di @ voyager sull’uso dell’attributo data-* (ad esempio data-gender="female|male" è l’approccio più efficace e conforms agli standard del 2017:

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

Quasi tutti gli obiettivi possono essere raggiunti in quanto vi sono alcuni, anche se limitati, selettori orientati al testo. La prima lettera è uno pseudoelemento che può applicare lo stile limitato alla prima lettera di un elemento. C’è anche uno pseudo-elemento :: first-line oltre a selezionare ovviamente la prima riga di un elemento (come un paragrafo) implica anche che è ovvio che i CSS potrebbero essere usati per estendere questa capacità esistente allo stile di aspetti specifici di un textNode .

Fino a quando tale advocacy ha successo e viene implementata la cosa migliore che potrei suggerire, quando applicabile, è explode / split parole usando un delimitatore spaziale, emettere ogni singola parola all’interno di un elemento span e quindi se l’objective parola / styling è prevedibile utilizzare in combinazione con : nth selettori :

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

Altrimenti se non è prevedibile , di nuovo, utilizzare la risposta di voyager sull’uso dell’attributo data-* . Un esempio con PHP:

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

Sono d’accordo sull’attributo dei dati (la risposta del voyager) è come dovrebbe essere gestito, MA, le regole CSS come:

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

spesso può essere molto più facile da configurare, specialmente con le librerie client come angularjs che potrebbero essere semplici come:

  

Assicurati che il contenuto sia solo una parola! Oppure potresti persino associare a diversi nomi di classi CSS con:

  

Per completezza, ecco l’approccio per l’attributo dei dati:

  

La maggior parte delle risposte qui tenta di offrire un’alternativa a come scrivere il codice HTML per includere più dati perché almeno fino a CSS3 non è ansible selezionare un elemento tramite il testo interno parziale. Ma può essere fatto, devi solo aggiungere un po ‘di JavaScript vaniglia, nota poiché la femmina contiene anche il maschio che sarà selezionato:

  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

Se usi Chimp / Webdriver.io , supportano molti più selettori CSS rispetto alle specifiche CSS.

Questo, ad esempio, farà clic sulla prima ancora che contiene le parole “Bad bear”:

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