特定のテキストを含む要素のCSSセレクターはありますか?


512

次の表のCSSセレクターを探しています。

Peter    | male    | 34
Susanne  | female  | 12

「男性」を含むすべてのTDに一致するセレクターはありますか?


1
問題は、これを高性能な方法で実装することが非常に難しいことです。
Ms2ger、2009年

7
XPathセレクターは、.text()メソッドを使用してそれを実行できます(JavaScript executorを使用したくない場合)。
djangofan 2013

11
xpathを使用してこれを行う方法の例を次に示します。// h1 [text()= 'Session']と入力し、Chromeでxpathをテストできます)コンソールで
VinnyG 2013年

1
これはとても便利でしょう。たとえば、チェックマークまたは「はい」、「パス」、「OK」などの文字列を含む表のセルは緑になる可能性があります。
Andreas Rejbrand 2014

$x質問に答えます。元の質問のために、$x("//td[text()='male']")トリックん

回答:


394

仕様を正しく読んだ場合、違います。

要素、要素内の属性の名前、および要素内の名前付き属性の値を照合できます。しかし、要素内のコンテンツに一致するものは何も表示されません。


228
エッジケースは1つです:empty
Ciro Santilli郝海东冠状病六四事件法轮功

34
私自身の質問に答えるには:はい、それは今日でもまだ当てはまります!コンテンツセレクタは廃止されました。CSS3以降、コンテンツセレクターはありません。(w3.org/TR/css3-selectors/#selectors
WLAD

158

jQueryの使用:

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

7
結局、これとは逆のjQuery(element).not( ":contains( 'string')")
Jazzy

311
それがCSSではないことを除いて、それはJavaScriptです。
Synetech 2015

9
同意した-それが私の答えが私がCSSではなくjQueryを使用していると言った理由です。しかし、私の答えのその部分は編集されました。=)
moettinger 2015

18
しかし、男性男性という単語自体にも「男性」という単語が含まれていますか?それはちょうど「cos男性が最初です」と働いていますか?再注文した場合、バグが発生するのを待っていますか?
Michael Durrant

5
@Michael Durrant:冗談ですが、要素間の文字列照合(同じ要素内の通常の部分文字列照合よりもさらに大きな問題です)は、実際には:contains()が削除された最大の理由の1つです。
BoltClock

158

彼らはCSS3仕様についてそれについて考えていたように見えますが、それはうまくいきませんでした

:contains()CSS3セレクターhttp://www.w3.org/TR/css3-selectors/#content-selectors


9
Looks like they were thinking about it for the CSS3 spec but it didn't make the cut.そして、それは正当な理由で、スタイル、コンテンツ、構造、および動作を分離するという前提全体に違反します。
Synetech 2015

56
@Synetechこれは、コンテンツがそのクライアントについて知る必要がないことを意味するので、コンテンツからスタイリングを分離するのを実際に助けることができます。現在、HTMLコンテンツは通常、スタイラーが気にするクラスを含めることにより、CSSと密接にペアリングされています。CSS3の属性値セレクターで証明されているように、コンテンツでCSSを許可する方向にすでにシフトしています。
DannyMeister 2015

8
@Synetech、そしてそれはどのように「振る舞い」ですか?私にとってそれはプレゼンテーションの問題です。それはしない何かを-それは提示し、特定の方法で特定のタイプのコンテンツを。
BarbaraKwarc 2017

4
@DannyMeister、ああ、あなたは私を説得する必要はありません。数年後、私はこの機能を正確に探そうとしているときにここに戻ってきました。そして、それが存在しないだけでなく、拒否されたことに腹を立てました。😒eBayはUIを変更し、サイトを使いにくくしました。ユーザースタイルシートで修正しようとしていますが、マークアップではオークションとBINリストが区別されないため、リスト内の入札数を強調表示する唯一の方法は、テキストコンテンツで要素を照合することです。誰かを説得するために必要なことは、ユーザーがユースケースのシナリオを直接体験することです。
Synetech

8
コンテンツとスタイルを適切に分離するために、:contains()セレクターはありません。したがって、セルのコンテンツ(「開く」の「ステータス」列、または「解決済み」など)に基づいてセルのスタイルを設定する代わりに、表示とクラス属性の両方でコンテンツを複製し、その上で選択します。優秀な!
Jon Kloske

122

あなたはと呼ばれる行にデータ属性を追加する必要があるだろうdata-gendermaleか、female値と属性セレクタを使用します。

HTML:

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

CSS:

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

10
JavaScriptとCSSでカスタムデータ属性を使用しても問題ありません。データ属性を使用したMDNを
Michael Benjamin

1
data属性はその処理方法であることに同意しますが、td.maleのようなCSSルールは、特に次のような角度の場合に特に簡単に設定できます:<td class = "{{person.gender}} ">
DJDaveMark

もちろん、性別はクラスが機能する典型的な例です。しかし、データが単にmaleまたはそれ以上に変化している場合はどうなりますかfemaleclass他のクラスで満たされているという事実、それらの順序は保証されていません、他のクラス名との衝突があるかもしれませんなどはclass、この種のものにとってより悪い場所になります。専用のdata-*属性は、データをそのすべてのものから分離し、属性セレクターを使用して部分的なマッチングなどを簡単に実行できるようにします。
Stijn de Witt

同様の方法でデータ属性を使用する実際のコードスニペットには別の答えがあります。
Josh Habdas

65

これが実装されていない理由には、実際には非常に概念的な根拠があります。これは基本的に3つの側面の組み合わせです。

  1. 要素のテキストコンテンツは、事実上その要素の子です
  2. テキストコンテンツを直接ターゲティングすることはできません
  3. CSSはセレクターによる昇天を許可していません

これら3つを合わせて、テキストコンテンツを取得するまでに、上位の要素に戻ることはできず、現在のテキストのスタイルを設定することはできません。降順ではコンテキストとSAXスタイルの解析の単一追跡のみが可能であるため、これはおそらく重要です。他の軸を含む昇順または他のセレクターは、CSSのDOMへの適用を非常に複雑にする、より複雑なトラバーサルまたは同様のソリューションの必要性をもたらします。


4
これは本当です。これがXPathの目的です。(CSSのみではなく)JS / jQueryまたは解析ライブラリでセレクターを実行できる場合は、XPathのtext()関数を使用することができます。
マークトーマス

これがコンテンツの良い点です。しかし:contains(<sub-selector>)、他の特定の要素を含む要素を選択する方法を教えてください。div:contains(div[id~="bannerAd"])広告とそのコンテナを取り除くのが好きです。
ローレンスドル

27

次に示すように、コンテンツをデータ属性として設定し、属性セレクターを使用できます

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

3
ノート.text().textContentかなり重いので、可能な場合は長いリストや大きなテキストにそれらを避けるようにしてください。.html().innerHTML高速です。
oriadam

@JoshHabdas変更のjsbin / jsfiddleの例を作成できますか?
Buksy

1
:あなたはjQueryのを使用しようとしている場合は、セレクタが含まれている使用$("td:contains(male)")
huwiler

ユーザーがコンテンツを編集できる場合(contenteditable='true'私の場合)、data-contentページがレンダリングされる前に属性の値を設定するだけでは不十分です。継続的に更新する必要があります。ここで私が使用するもの:<td onkeypress="event.target.setAttribute('data-content', event.target.textContent);">
caram

13

CSSにはこの機能がないため、JavaScriptを使用してコンテンツによってセルのスタイルを設定する必要があります。たとえばXPathの場合contains

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/


これはjavascriptです、これは質問とどのように関連していますか?
rubo77

3
cssのコンテンツで選択できないため、jsを使用してそれを行う必要があります。これはcssではないという指摘は正しいですが、データ属性の使用はコンテンツによって選択されていません。読者がコンテンツでセルを選択する理由、HTMLへのアクセスの種類、一致の数、テーブルの大きさなどを推測することしかできません
user40521


4

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

これは、私の場合は常に1つの要素であるため、複数ある場合は最初の要素を返します。


あなたは使用することができTD:contains('male')ますが、セレンを使用している場合:あなたがクラスを追加するには、ソースを更新できない場合私見は、それを使用しています。たとえば、レガシーコードをテストしている場合、または会社が開発者に話しかけることを許可しない場合(eurgh!)は、テストが脆弱であり、誰かが後でテキストをmasculine変更したり言語を変更したりすると壊れます。SauceLabs docsはcontainsここの使用法を示しています(saucelabs.com/resources/articles/selenium-tips-css-selectors)+ cc @matas vaitkevicius何かを見逃しましたか?
スノーコード2019年

3

data属性(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}}">

テンプレートバインディングは優れたソリューションです。しかし、マークアップ構造に基づいてクラス名を作成するのは少し不快に感じます(BEMが実際に行うことはほとんどそれです)。
Josh Habdas

2

data-*属性の使用に関する@voyagerの回答(例:2017年の時点でdata-gender="female|male"最も効果的で標準に準拠したアプローチ:

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

テキストを中心とした限られたセレクターもありますが、ほとんどの目的達成できます。::最初の文字である擬似要素要素の最初の文字に限定スタイルを適用することができます。あります::最初の行の擬似要素は、(例えば、段落など)は明らかに要素の最初の行を選択する以外にも、CSSがtextNodeのスタイルの特定の側面には、この既存の機能を拡張するために使用することができることが明らかであることを意味し。

そのようなアドボカシーが成功て実装されるまで、私が提案できる次の最高のものは、スペースデリミネーターを使用したexplode/ splitワードです。span要素内の個々のワードを出力し、ワード/スタイリングの目標:nthセレクターと組み合わせて予測可能な使用かどうかを示します。:

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

それ以外の場合は、予測できない場合はdata-*属性の使用に関するボイジャーの回答を使用します。PHPの使用例:

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


1

ここでの回答のほとんどは、HTMLコードを記述してより多くのデータを含める方法に代わるものを提供しようとしています。これは、少なくともCSS3までは、部分的な内部テキストで要素を選択できないためです。しかし、それは可能です。ちょっとしたバニラ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>

1

JavaScriptまたはjqueryを使用したくない場合は、属性オプションが最善の策であると思います。

たとえば、readyという単語ですべてのテーブルセルをスタイルするには、HTMLで次のようにします。

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

次にCSSで:

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

0

また、使用することができcontentattr()いるスタイルテーブルのセルと::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は色を変更するために使用され、バニラJavaScriptを使用して追加できます。

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

けれども<td>sの終了タグを省略することができるようにすること、それが空でないものとして扱われる可能性があります。


0

自分でDOMを作成しない場合(たとえば、ユーザースクリプトで)、純粋な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>

コンソール出力

text: <td> Peter
text: <td> male
text: <td> 34
text: <td> Susanne
text: <td> female
text: <td> 12
male: <td text="male"> male

-2

次のような小さなフィルターウィジェットを実行します。

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

-2

この質問の構文は、ロボットフレームワークの構文に似ています。この場合、containsに使用できるcssセレクターはありませんが、代わりに使用できるSeleniumLibraryキーワードがあります。要素まで待つが含まれてい

例:

Wait Until Element Contains  | ${element} | ${contains}
Wait Until Element Contains  |  td | male
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.