コンテンツの完全一致によって要素を選択します


160

:contains()さて、jQueryのセレクターに、入力された文字列のみを含む要素を選択する方法があるかどうか疑問に思います

例えば ​​-

<p>hello</p>
<p>hello world</p>

$('p:contains("hello")').css('font-weight', 'bold');

セレクターは両方のp要素を選択して太字にしますが、最初の要素のみを選択するようにします。


まあ、あなたは:contains自分のコードでセレクターをオーバーライドすることができますが、それがあなたの意図したことではないと思いますか?
Blazemonger 2013年


:カスタムセレクタを定義できstackoverflow.com/questions/12244929/...
BLSully


回答:


214

いいえ、それを行うjQuery(またはCSS)セレクターはありません。

あなたはすぐに使うことができますfilter

$("p").filter(function() {
    return $(this).text() === "hello";
}).css("font-weight", "bold");

これはセレクタではありませんが、機能します。:-)

「hello」の前または後に空白を処理したい場合は$.trim、そこにa をスローします。

return $.trim($(this).text()) === "hello";

そこに時期尚早オプティマイザのために、あなたはそれが一致していないことを気にしない場合<p><span>hello</span></p>と同様に、あなたがへの呼び出しを回避することができます$し、text使用してinnerHTML直接に:

return this.innerHTML === "hello";

...しかし、問題になるには多くの段落が必要になるため、最初に他の問題が発生する可能性があります。:-)


7
$.trim比較を行う前に、不要な空白を削除したい場合もあります。
Blazemonger 2013年

何らかの理由で、「===」の代わりに「==」を使用して機能させる必要がありました。
Stephan

3
@Stephan:あなたは数と比較した場合、あなたはどちらかを使用する必要があると思います==== 2)または文字列に数値を入れ(=== "2")、あなたから得る価値あるためtext()かはinnerHTML常に文字列です。文字列と比較する場合、==またはを使用するかどうかは関係ありません===
TJクラウダー2015年

jQueryが:containsより複雑に実装したのは残念ですが、テキストを完全に一致させるためのセレクターを実装していません。= {
パウロブエノ

54

拡張疑似関数を追加してみてください:

$.expr[':'].textEquals = $.expr.createPseudo(function(arg) {
    return function( elem ) {
        return $(elem).text().match("^" + arg + "$");
    };
});

その後、次のことができます。

$('p:textEquals("Hello World")');

2
最適なソリューション:少し加えて:あなたは、既存の式exprを上書きしないようにするために、私はどうなる:$.expr[':'].textEquals = $.expr[':'].textEquals || $.expr.createPseudo(function(arg) {
ミーシャMolhoek

9

これを実現するには、jQueryのfilter()関数を使用できます。

$("p").filter(function() {
// Matches exact string   
return $(this).text() === "Hello World";
}).css("font-weight", "bold");

9

したがって、アマンドゥの答えはほとんど機能します。しかし、実際にそれを使用していると、私はいくつかの問題に遭遇しました。これは、要素のテキストの周囲にランダムな空白が時々あるためです。「Hello World」を検索している場合でも、「Hello World」または「Hello World \ n」に一致させることをお勧めします。したがって、関数に「trim()」メソッドを追加するだけで、周囲の空白が削除され、機能が向上し始めました。

具体的には...

$.expr[':'].textEquals = function(el, i, m) {
    var searchText = m[3];
    var match = $(el).text().trim().match("^" + searchText + "$")
    return match && match.length > 0;
}

また、この回答はテキストによるリンクの選択(完全一致)と非常に似てい ます。

二次メモ... 検索されたテキストの前後のtrim空白のみを削除します。単語の途中にある空白は削除されません。これは望ましい動作ですが、必要に応じて変更できます。


5

私は自分に合った方法を見つけました。100%正確ではありませんが、個々のスペースを含まない文字列もチェックするため、探している単語だけではない文字列をすべて削除します。ちなみに、これらは必要ありません ""。jQueryは、文字列を探していることを認識しています。:contains()の部分にスペースが1つしかないことを確認してください。そうしないと機能しません。

<p>hello</p>
<p>hello world</p>
$('p:contains(hello):not(:contains( ))').css('font-weight', 'bold');

そして、はい、私はあなたが次のようなものを持っている場合は機能しないことを知っています <p>helloworld</p>


1
フィルターや拡張機能を使用せずに、contains(..)を使用した単純な一致の巧妙な使用法!最初のcontains(..)にスペースを必要とするものには取り組みませんが、その解決策を考え出そうとしています。ありがとう!
JoePC 2018

3

上記のTJ Crowderのように、フィルター機能は不思議です。私の場合、それは私にはうまくいきませんでした。複数のテーブルとそれぞれのtdタグをdiv(この場合はjQueryダイアログ)内で検索​​する必要がありました。

$("#MyJqueryDialog table tr td").filter(function () {
    // The following implies that there is some text inside the td tag.
    if ($.trim($(this).text()) == "Hello World!") {
       // Perform specific task.
    }
});

これが誰かに役立つことを願っています!


私はjqueryにかなり慣れていますが、filterの目的はサブ配列を返すことなので、filter()の代わりにeach()を使用する方が少し良いと思います。しかし、私が同じ問題を抱えていたので、解決策を明確に刺激しました:)
JeopardyTempest

0

jQueryの代替ライブラリと連携するワンライナー:

$('p').filter((i, p) => $(p).text().trim() === "hello").css('font-weight', 'bold');

そして、これはjQueryのa:contains("pattern")セレクターと同等です。

var res = $('a').filter((i, a) => $(a).text().match(/pattern/));

-4

.first()はここで役立ちます

$('p:contains("hello")').first().css('font-weight', 'bold');

確かに...この特定のケースでは。開発時に注文が不明な場合はどうなりますか?
BLSully 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.