Pilih elemen berdasarkan kecocokan yang tepat dari isinya

161

Baiklah, saya bertanya-tanya apakah ada cara untuk membuat :contains()pemilih jQuery untuk memilih elemen dengan hanya string yang diketikkan

sebagai contoh -

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

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

Pemilih akan memilih kedua pelemen dan membuatnya tebal, tapi saya ingin hanya memilih yang pertama.

julian
sumber
Nah, Anda bisa mengganti :containspemilih dengan kode Anda sendiri, tapi saya kira itu bukan maksud Anda?
Blazemonger
Anda dapat menentukan pemilih khusus: stackoverflow.com/questions/12244929/...
BLSully
Kemungkinan rangkap: pemilih Jquery, mengandung yang sama dengan
BinaryTox1n
kemungkinan rangkap dari tautan Pilih dengan teks (pencocokan persis)
FishBasketGordo

Jawaban:

215

Tidak, tidak ada pemilih jQuery (atau CSS) yang melakukan itu.

Anda dapat dengan mudah menggunakan filter:

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

Ini bukan pemilih , tapi itu berfungsi. :-)

Jika Anda ingin menangani spasi putih sebelum atau setelah "halo", Anda dapat melemparkan $.trimdi sana:

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

Untuk pengoptimal prematur di luar sana, jika Anda tidak peduli itu tidak cocok <p><span>hello</span></p>dan serupa, Anda dapat menghindari panggilan ke $dan textdengan menggunakan innerHTMLlangsung:

return this.innerHTML === "hello";

... tetapi Anda harus memiliki banyak paragraf agar itu penting, begitu banyak sehingga Anda mungkin memiliki masalah lain terlebih dahulu. :-)

TJ Crowder
sumber
7
Mungkin juga ingin $.trimitu dari spasi putih menyimpang sebelum membuat perbandingan.
Blazemonger
Untuk beberapa alasan saya harus menggunakan "==" agar ini berfungsi, bukan "===".
Stephan
3
@Stephan: Jika Anda membandingkan dengan angka, Anda harus menggunakan ==( == 2) atau memasukkan nomor ke dalam string ( === "2"), karena nilai yang Anda peroleh dari text()atau innerHTMLselalu berupa string. Jika Anda membandingkan dengan string, tidak masalah apakah Anda menggunakan ==atau ===.
TJ Crowder
Sayang sekali bahwa jQuery telah menerapkan :containsyang agak lebih kompleks, tetapi belum menerapkan pemilih untuk pencocokan teks yang tepat. = {
Paulo Bueno
54

Coba tambahkan fungsi extended pseudo:

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

Maka Anda dapat melakukan:

$('p:textEquals("Hello World")');
Amadu Bah
sumber
2
solusi hebat: sedikit tambahan: untuk memastikan Anda tidak menimpa expr yang ada, saya akan melakukan:$.expr[':'].textEquals = $.expr[':'].textEquals || $.expr.createPseudo(function(arg) {
Mischa Molhoek
9

Anda dapat menggunakan fungsi filter () jQuery untuk mencapai ini.

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

Jadi jawaban Amandu kebanyakan berhasil. Namun, menggunakannya di alam liar, saya mengalami beberapa masalah, di mana hal-hal yang saya harapkan tidak ditemukan. Ini karena kadang-kadang ada ruang putih acak di sekitar teks elemen. Adalah keyakinan saya bahwa jika Anda mencari "Hello World", Anda masih ingin itu cocok dengan "Hello World", atau bahkan "Hello World \ n". Jadi, saya baru saja menambahkan metode "trim ()" ke fungsi, yang menghilangkan spasi putih, dan mulai bekerja lebih baik.

Secara khusus...

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

Perhatikan juga, jawaban ini sangat mirip dengan Pilih tautan menurut teks (kecocokan persis)

Dan catatan sekunder ... trimhanya menghilangkan spasi putih sebelum dan sesudah teks yang dicari. Itu tidak menghapus spasi di tengah kata-kata. Saya percaya ini adalah perilaku yang diinginkan, tetapi Anda bisa mengubahnya jika Anda mau.

bwest87
sumber
5

Saya menemukan cara yang bekerja untuk saya. Ini tidak 100% tepat tetapi menghilangkan semua string yang mengandung lebih dari sekedar kata yang saya cari karena saya memeriksa string yang tidak mengandung spasi individual juga. Ngomong-ngomong kamu tidak butuh ini "". jQuery tahu Anda sedang mencari string. Pastikan Anda hanya memiliki satu ruang di bagian: berisi () jika tidak, tidak akan berfungsi.

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

Dan ya saya tahu itu tidak akan berhasil jika Anda memiliki barang seperti <p>helloworld</p>

rf1234
sumber
1
Penggunaan cerdik dari kecocokan sederhana dengan berisi (..) tanpa menggunakan filter atau ekstensi! Tidak akan bekerja pada apa pun yang membutuhkan ruang di pertama berisi (..), tetapi mencoba untuk menemukan solusi untuk itu. Terima kasih!
JoePC
3

Seperti TJ Crowder yang disebutkan di atas, fungsi filter memang menakjubkan. Itu tidak bekerja untuk saya dalam kasus khusus saya. Saya perlu mencari beberapa tabel dan masing-masing tag td di dalam div (dalam hal ini dialog 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.
    }
});

Saya harap ini membantu seseorang!

Greg A
sumber
Saya cukup baru di jquery, tetapi saya pikir akan sedikit lebih baik menggunakan masing-masing () daripada filter () karena tujuan filter adalah mengembalikan subarray. Tetapi mengilhami solusinya pasti, karena saya memiliki masalah yang sama :)
JeopardyTempest
0

Satu baris yang berfungsi dengan pustaka alternatif untuk jQuery:

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

Dan ini setara dengan a:contains("pattern")pemilih jQuery :

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

.First () akan membantu di sini

$('p:contains("hello")').first().css('font-weight', 'bold');
tymeJV
sumber
Tentu ... dalam kasus khusus ini. bagaimana jika pesanannya tidak diketahui pada waktu dev?
BLSully