เลือกองค์ประกอบตามการจับคู่ที่แน่นอนของเนื้อหา


161

เอาล่ะฉันสงสัยว่ามีวิธีที่จะทำให้:contains()ตัวเลือกของ jQuery เพื่อเลือกองค์ประกอบที่มีเฉพาะสตริงที่พิมพ์

ตัวอย่างเช่น -

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

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

ตัวเลือกจะเลือกpองค์ประกอบทั้งสองและทำให้เป็นตัวหนา แต่ฉันต้องการให้เลือกเฉพาะองค์ประกอบแรก


คุณสามารถแทนที่:containsตัวเลือกด้วยรหัสของคุณเอง แต่ฉันไม่คิดว่านั่นคือสิ่งที่คุณหมายถึง?
Blazemonger


คุณสามารถกำหนดตัวเลือกที่กำหนดเองได้: stackoverflow.com/questions/12244929/…
BLSully

สำเนาซ้ำที่เป็นไปได้ของ: ตัวเลือก jquery มีค่าเท่ากับ
BinaryTox1n

คำตอบ:


215

ไม่ไม่มีตัวเลือก jQuery (หรือ CSS) ที่ทำเช่นนั้น

คุณสามารถใช้filter:

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

มันไม่ใช่ตัวเลือกแต่ทำงานได้ :-)

หากคุณต้องการจัดการกับช่องว่างก่อนหรือหลัง "สวัสดี" คุณอาจจะใส่$.trimใน:

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

สำหรับการเพิ่มประสิทธิภาพก่อนวัยอันควรถ้าคุณไม่สนใจว่ามันไม่ตรง<p><span>hello</span></p>และคล้ายกันคุณสามารถหลีกเลี่ยงการโทร$และtextโดยใช้innerHTMLโดยตรง:

return this.innerHTML === "hello";

... แต่คุณต้องมีหลายย่อหน้าเพื่อให้มันมีความสำคัญมากที่คุณอาจมีปัญหาอื่นก่อน :-)


7
อาจต้องการ$.trimช่องว่างใด ๆ ที่หลงทางก่อนที่จะทำการเปรียบเทียบ
Blazemonger

ด้วยเหตุผลบางอย่างฉันต้องใช้ "==" เพื่อให้สิ่งนี้ทำงานแทน "==="
เตฟาน

3
@Stephan: หากคุณเปรียบเทียบกับตัวเลขคุณจะต้องใช้==( == 2) หรือใส่ตัวเลขในสตริง ( === "2") เนื่องจากค่าที่คุณได้รับมาจากtext()หรือinnerHTMLเป็นสตริงเสมอ ถ้าคุณได้รับเมื่อเทียบกับสตริงมันไม่สำคัญว่าคุณจะใช้หรือ== ===
TJ Crowder

มันเป็นความอัปยศที่ jQuery ได้นำไปใช้:containsซึ่งมีความซับซ้อนมากกว่า แต่ก็ยังไม่ได้ใช้ตัวเลือกสำหรับการจับคู่ข้อความที่ตรงกัน = {
Paulo Bueno

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) {
Mischa Molhoek

9

คุณสามารถใช้ฟังก์ชันตัวกรองของ jQuery ()เพื่อให้ได้สิ่งนี้

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

9

ดังนั้นคำตอบของ Amandu จึงเป็นไปได้มากที่สุด อย่างไรก็ตามการใช้งานในป่าฉันพบปัญหาบางอย่างซึ่งสิ่งที่ฉันคาดว่าจะได้พบไม่ได้รับพบ นี่เป็นเพราะบางครั้งมีพื้นที่สีขาวแบบสุ่มล้อมรอบข้อความขององค์ประกอบ ฉันเชื่อว่าหากคุณกำลังค้นหา "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 รู้ว่าคุณกำลังมองหาสตริง ตรวจสอบให้แน่ใจว่าคุณมีที่ว่างเพียงส่วนเดียวใน: contain () มิฉะนั้นจะไม่สามารถใช้งานได้

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

และใช่ฉันรู้ว่ามันจะไม่ทำงานหากคุณมีสิ่งที่ชอบ <p>helloworld</p>


1
การใช้งานการจับคู่อย่างง่ายอย่างชาญฉลาดด้วยการบรรจุ (.. ) โดยไม่ต้องใช้ตัวกรองหรือส่วนขยาย! จะไม่ทำงานในสิ่งที่ต้องการช่องว่างในตอนแรกมี (.. ) แต่พยายามหาวิธีแก้ปัญหาสำหรับสิ่งนั้น ขอบคุณ!
JoePC

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 () เนื่องจากเป้าหมายของตัวกรองคือการส่งคืน subarray แต่เป็นแรงบันดาลใจให้แก้ปัญหาแน่นอนเพราะฉันมีปัญหาเดียวกัน :)
JeopardyTempest

0

สายการบินเดียวที่ทำงานร่วมกับห้องสมุดทางเลือกเพื่อ jQuery:

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

และนี่คือสิ่งที่เทียบเท่ากับa:contains("pattern")ตัวเลือกของ jQuery :

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

-4

. first () จะช่วยที่นี่

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

แน่นอน ... ในกรณีนี้โดยเฉพาะ เกิดอะไรขึ้นถ้าคำสั่งไม่เป็นที่รู้จักในเวลา dev?
BLSully
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.