Öğeyi içeriğiyle tam olarak eşleştirerek seçme


161

Tamam, :contains()jQuery seçicisini yalnızca yazılan dizeyle öğeleri seçmek için yapmanın bir yolu olup olmadığını merak ediyorum

Örneğin -

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

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

Seçici her iki pöğeyi de seçer ve onları kalın yapar, ancak yalnızca ilkini seçmesini istiyorum.


Peki, :containsseçiciyi kendi kodunuzla geçersiz kılabilirsiniz , ama ne demek istediğini sanmıyorum?
Blazemonger


Özel bir seçici tanımlayabilirsiniz: stackoverflow.com/questions/12244929/…
BLSully


Yanıtlar:


215

Hayır, bunu yapan jQuery (veya CSS) seçici yoktur.

Kolayca kullanabilirsiniz filter:

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

Bu bir seçici değil , ama işi yapıyor. :-)

Eğer boşluktan "merhaba" dan önce ya da sonra işlemek istiyorsanız $.trim, oraya bir atabilirsiniz :

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

Orada bulunan erken optimize ediciler için, eşleşmediği <p><span>hello</span></p>ve benzeri olmadığına dikkat etmezseniz, doğrudan $ve textkullanarak aramalardan kaçınabilirsiniz innerHTML:

return this.innerHTML === "hello";

... ama önemli olması için çok fazla paragrafa sahip olmanız gerekir , o kadar çok ki muhtemelen ilk önce başka sorunlarınız olur. :-)


7
$.trimKarşılaştırma yapmadan önce herhangi bir başıboş boşluk olmasını da isteyebilir .
Blazemonger

Nedense bunun çalışması için "===" yerine "==" kullanmak zorunda kaldım.
Stephan

3
@Stephan: Bir sayıyla karşılaştırıyorsanız, aldığınız veya her zaman bir dize olduğu için numarayı ==( == 2) kullanmanız veya sayıyı bir dizeye ( === "2") koymanız gerekir . Bir dize ile karşılaştırma yapıyorsanız, veya kullanmanızın bir önemi yoktur . text()innerHTML=====
TJ Crowder

:containsJQuery'nin biraz daha karmaşık olduğu, ancak tam metin eşleşmesi için bir seçici uygulamadığı bir utanç . = {
Paulo Bueno

54

Genişletme sözde işlevi eklemeyi deneyin:

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

Sonra şunları yapabilirsiniz:

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

2
harika bir çözüm: küçük bir ekleme: mevcut bir ifade üzerine $.expr[':'].textEquals = $.expr[':'].textEquals || $.expr.createPseudo(function(arg) {
yazmadığınızdan

9

Bunu başarmak için jQuery'nin filter () işlevini kullanabilirsiniz.

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

9

Amauu'nun cevabı çoğunlukla işe yarıyor. Bununla birlikte, vahşi doğada kullanmak, bulmayı umduğum şeylerin bulunmadığı bazı sorunlarla karşılaştım. Bunun nedeni bazen öğenin metnini çevreleyen rastgele beyaz boşluk olmasıdır. Benim inancım, "Merhaba Dünya" arıyorsanız, yine de "Merhaba Dünya", hatta "Merhaba Dünya \ n" ile eşleşmesini isteyeceksiniz. Böylece, fonksiyona çevreleyen boşluğu kaldıran "trim ()" yöntemini ekledim ve daha iyi çalışmaya başladı.

Özellikle ...

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

Ayrıca, bu yanıtın Metne göre bağlantı seç (tam eşleme) ile çok benzer olduğunu unutmayın.

Ve ikincil not ... trimsadece aranan metnin önündeki ve sonundaki boşlukları kaldırır . Kelimelerin ortasındaki boşlukları kaldırmaz. Bunun arzu edilen bir davranış olduğuna inanıyorum, ancak isterseniz bunu değiştirebilirsiniz.


5

Benim için işe yarayan bir yol buldum. % 100 kesin değil ama ben de tek tek boşluk içermeyen dize kontrol çünkü ben sadece aradığım kelimeden daha fazlasını içeren tüm dizeleri ortadan kaldırır. Bu arada bunlara ihtiyacınız yok "". jQuery bir dize aradığınızı bilir. : İnclude () bölümünde yalnızca bir alan bulunduğundan emin olun, aksi takdirde çalışmaz.

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

Ve evet, bunun gibi şeyler varsa işe yaramayacağını biliyorum <p>helloworld</p>


1
Bir filtre veya uzantı kullanmadan içeren (..) ile basit eşleşmelerin akıllı kullanımı! İlk içerir boşluk gerektiren hiçbir şey üzerinde çalışmayacak içerir (..), ama bunun için bir çözüm bulmaya çalışıyor. Teşekkürler!
JoePC

3

TJ Crowder'ın yukarıda belirttiği gibi, filtre işlevi harikalar yaratıyor. Benim özel durumumda benim için işe yaramıyordu. Birden fazla tablo ve bir div (bu durumda bir jQuery iletişim kutusu) içinde ilgili td etiketleri aramak gerekiyordu.

$("#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.
    }
});

Umarım bu birisi için faydalıdır!


Jquery için oldukça yeniyim, ancak filtrenin amacı bir alt diziyi döndürmek olduğundan filter () yerine her () kullanmak biraz daha iyi olur. Ama aynı sorunları vardı gibi, çözüm kesinlikle ilham :)
JeopardyTempest

0

JQuery'ye alternatif kütüphanelerle çalışan tek astar :

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

Ve bu bir jQuery a:contains("pattern")seçicisine eşdeğerdir :

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

-4

.First () burada yardımcı olacaktır

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

Elbette ... bu özel durumda. ya sipariş dev anda bilinmiyorsa ne olacak?
BLSully
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.