Is er een CSS-selector voor elementen die bepaalde tekst bevatten?

Ik ben op zoek naar een CSS-selector voor de volgende tabel:

Peter    | male    | 34
Susanne  | female  | 12

Is er een selector die overeenkomt met alle TD’s die “mannelijk” bevatten?


Antwoord 1, autoriteit 100%

Als ik de specificatie correct lees, nee.

Je kunt op een element de naam van een attribuut in het element en de waarde van een benoemd attribuut in een element matchen. Ik zie echter niets voor overeenkomende inhoud binnen een element.


Antwoord 2, autoriteit 39%

Het lijkt erop dat ze erover nadachten voor de CSS3-specificatie maar het haalde het niet.

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


Antwoord 3, autoriteit 35%

JQuery gebruiken:

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

Antwoord 4, autoriteit 29%

U moet een gegevenskenmerk toevoegen aan de rijen met de naam data-gender met een waarde male of female en het kenmerk gebruiken kiezer:

HTML:

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

CSS:

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

Antwoord 5, autoriteit 15%

Er is eigenlijk een zeer conceptuele basis waarom dit niet is geïmplementeerd. Het is een combinatie van in principe 3 aspecten:

  1. De tekstinhoud van een element is in feite een onderliggend element van dat element
  2. U kunt de tekstinhoud niet rechtstreeks targeten
  3. CSS staat geen ascensie toe met selectors

Deze 3 samen betekenen dat tegen de tijd dat je de tekstinhoud hebt, je niet terug kunt stijgen naar het bevattende element en dat je de huidige tekst niet kunt opmaken. Dit is waarschijnlijk belangrijk omdat aflopend alleen een enkelvoudig volgen van context en ontleding in SAX-stijl mogelijk maakt. Ascenderende of andere selectors waarbij andere assen betrokken zijn, introduceren de behoefte aan complexere traversal of vergelijkbare oplossingen die de toepassing van CSS op de DOM aanzienlijk zouden bemoeilijken.


Antwoord 6, autoriteit 8%

U kunt inhoud instellen als gegevenskenmerk en vervolgens kenmerkkiezers, zoals hier getoond:

/* 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-content="Susanne">Susanne</td>
    <td data-content="female">female</td>
    <td data-content="14">14</td>
  </tr>
</table>

Antwoord 7, autoriteit 4%

Omdat CSS deze functie niet heeft, moet u JavaScript gebruiken om cellen op inhoud te stylen. Bijvoorbeeld met XPath’s contains:

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

Gebruik het resultaat dan als volgt:

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

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


Antwoord 8

Ik ben bang dat dit niet mogelijk is, omdat de inhoud geen attribuut is en ook niet toegankelijk is via een pseudo-klasse. De volledige lijst met CSS3-selectors is te vinden in de CSS3-specificatie.


Antwoord 9

Voor degenen die Selenium CSS-tekstselecties willen doen, kan dit script van enig nut zijn.

De truc is om de ouder van het element dat je zoekt te selecteren en vervolgens te zoeken naar het kind met de tekst:

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

Hiermee wordt het eerste element geretourneerd als er meer dan één is, omdat het in mijn geval altijd één element is.


Antwoord 10

Ik ben het ermee eens dat het gegevenskenmerk (het antwoord van de reiziger) is hoe het moet worden afgehandeld, MAAR , CSS-regels zoals:

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

kan vaak veel gemakkelijker in te stellen zijn, vooral met bibliotheken aan de clientzijde zoals angularjs, wat zo simpel kan zijn als:

<td class="{{person.gender}}">

Zorg er wel voor dat de inhoud maar uit één woord bestaat! Of je zou zelfs kunnen toewijzen aan verschillende CSS-klassenamen met:

<td ng-class="{'masculine': person.isMale(), 'feminine': person.isFemale()}">

Voor de volledigheid, hier is de data-attribuutbenadering:

<td data-gender="{{person.gender}}">

Antwoord 11

Vanaf januari 2021 IS er iets dat precies dit zal doen. :has() … slechts één addertje onder het gras: dit wordt nog in geen enkele browser ondersteund

Voorbeeld: de volgende selector komt alleen overeen met elementen die direct een kind bevatten:

a:has(> img)

Referenties:

https://developer.mozilla.org/en- VS/docs/Web/CSS/:has

https://caniuse.com/?search=has


Antwoord 12

Als je Chimp / Webdriver.io, ze ondersteunen nog veel meer CSS-kiezers dan de CSS-specificatie.

Dit zal bijvoorbeeld klikken op het eerste anker dat de woorden “Slechte beer” bevat:

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

Antwoord 13

Als u de DOM niet zelf maakt (bijvoorbeeld in een gebruikersscript), kunt u het volgende doen met pure JS:

for ( td of document.querySelectorAll('td') ) {
  console.debug("text:", td, td.innerText)
  td.setAttribute('text', td.innerText)
}
for ( td of document.querySelectorAll('td[text="male"]') )
  console.debug("male:", td, td.innerText)
<table>
  <tr>
    <td>Peter</td>
    <td>male</td>
    <td>34</td>
  </tr>
  <tr>
    <td>Susanne</td>
    <td>female</td>
    <td>12</td>
  </tr>
</table>

Antwoord 14

@voyager’s antwoord over het gebruik van het kenmerk data-* (bijv. data-gender="female|male" is het meest effectief en voldoet aan de normen aanpak vanaf 2017:

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

Vrijwel de meeste doelen kunnen worden bereikt, omdat er enkele, zij het beperkte, selectors zijn die op tekst zijn gericht. De ::first-letter is een pseudo-element dat een beperkte stijl kan toepassen op de eerste letter van een element. Er is ook een ::first-line pseudo-element naast het uiteraard selecteren van de eerste regel van een element (zoals een alinea) impliceert ook dat het voor de hand ligt dat CSS kan worden gebruikt om deze bestaande mogelijkheid uit te breiden om specifieke aspecten van een textNode te stylen.

Totdat dergelijke belangenbehartiging slaagt en is geïmplementeerd, is het beste wat ik zou kunnen voorstellen, indien van toepassing, het explode/split woorden met behulp van een spatiescheidingsteken , voer elk afzonderlijk woord uit binnen een span-element en als het woord/stylingdoel voorspelbaar is, gebruik het dan in combinatie met :nth selectors:

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

Anders indien niet voorspelbaar om opnieuw het antwoord van de voyager te gebruiken over het gebruik van het kenmerk data-*. Een voorbeeld met PHP:

$p = explode(' ',$words);
foreach ($p as $key1 => $value1)
{
 echo '<span data-word="'.$value1.'">'.$value1.'</span>;
}

Antwoord 15

De meeste antwoorden hier proberen een alternatief te bieden voor het schrijven van de HTML-code om meer gegevens op te nemen, omdat u ten minste tot aan CSS3 geen element kunt selecteren met gedeeltelijke binnentekst. Maar het kan worden gedaan, je hoeft alleen een beetje vanille JavaScript toe te voegen, let op, aangezien vrouwelijk ook mannelijk bevat, wordt het geselecteerd:

      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>

Antwoord 16

Ik vind de attribuutoptie de beste keuze als je geen javascript of jQuery wilt gebruiken.

Bijvoorbeeld om alle tabelcellen op te maken met het woord klaar, doe dit in HTML:

 <td status*="ready">Ready</td>

Vervolgens in css:

td[status*="ready"] {
        color: red;
    }

Antwoord 17

U kunt ook content gebruiken met attr() en stijl tabelcellen die :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>

Antwoord 18

Kleine filterwidgets als volgt doen:

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

Antwoord 19

De syntaxis van deze vraag lijkt op de Robot Framework-syntaxis.
In dit geval, hoewel er geen css-selector is die u kunt gebruiken voor bevat, is er een SeleniumLibrary-sleutelwoord dat u in plaats daarvan kunt gebruiken.
De Wacht tot element bevat.

Voorbeeld:

Wait Until Element Contains  | ${element} | ${contains}
Wait Until Element Contains  |  td | male

LEAVE A REPLY

Please enter your comment!
Please enter your name here

two + 13 =

Other episodes