Chọn thành phần theo kết hợp chính xác của nội dung của nó


160

Được rồi, tôi tự hỏi liệu có cách nào để tạo :contains()bộ chọn của jQuery để chọn các phần tử chỉ với chuỗi được nhập vào không

ví dụ -

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

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

Bộ chọn sẽ chọn cả hai pphần tử và làm cho chúng đậm, nhưng tôi muốn nó chỉ chọn phần tử đầu tiên.


Chà, bạn có thể ghi đè :containsbộ chọn bằng mã của riêng bạn, nhưng tôi không cho rằng đó là ý bạn?
Blazemonger


Bạn có thể xác định một bộ chọn tùy chỉnh: stackoverflow.com/questions/12244929/ từ
BLSully

Bản sao có thể có của: Bộ chọn Jquery, chứa bằng
BinaryTox1n

Câu trả lời:


214

Không, không có bộ chọn jQuery (hoặc CSS) nào thực hiện điều đó.

Bạn có thể dễ dàng sử dụng filter:

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

Nó không phải là một bộ chọn , nhưng nó thực hiện công việc. :-)

Nếu bạn muốn xử lý khoảng trắng trước hoặc sau "xin chào", bạn có thể ném $.trimvào đó:

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

Đối với các trình tối ưu hóa sớm ngoài kia, nếu bạn không quan tâm rằng nó không khớp <p><span>hello</span></p>và tương tự, bạn có thể tránh các cuộc gọi đến $textbằng cách sử dụng innerHTMLtrực tiếp:

return this.innerHTML === "hello";

... nhưng bạn phải có rất nhiều đoạn cho nó có vấn đề, rất nhiều điều mà trước tiên bạn có thể có vấn đề khác. :-)


7
Cũng có thể muốn $.trimnó của bất kỳ khoảng trắng đi lạc trước khi thực hiện so sánh.
Blazemonger

Vì một số lý do, tôi đã phải sử dụng "==" để làm việc này thay vì "===".
Stephan

3
@Stephan: Nếu bạn đang so sánh với một số, bạn phải sử dụng ==( == 2) hoặc đặt số đó vào một chuỗi ( === "2"), bởi vì giá trị bạn nhận được từ text()hoặc innerHTMLluôn luôn là một chuỗi. Nếu bạn đang so sánh với một chuỗi, việc bạn sử dụng ==hay ===.
TJ Crowder

Thật đáng tiếc khi jQuery đã triển khai :containswich thì phức tạp hơn, nhưng đã không triển khai một bộ chọn cho khớp văn bản chính xác. = {
Paulo Bueno

54

Hãy thử thêm chức năng giả mở rộng:

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

Sau đó, bạn có thể làm:

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

2
giải pháp tuyệt vời: ít bổ sung: để đảm bảo bạn không ghi đè lên một expr hiện có, tôi sẽ làm:$.expr[':'].textEquals = $.expr[':'].textEquals || $.expr.createPseudo(function(arg) {
Mischa Molhoek

9

Bạn có thể sử dụng hàm filter () của jQuery để đạt được điều này.

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

9

Vì vậy, câu trả lời của Amandu chủ yếu hoạt động. Tuy nhiên, sử dụng nó trong tự nhiên, tôi gặp phải một số vấn đề, trong đó những thứ mà tôi mong đợi sẽ được tìm thấy không được tìm thấy. Điều này là do đôi khi có khoảng trắng ngẫu nhiên xung quanh văn bản của phần tử. Tôi tin rằng nếu bạn đang tìm kiếm "Hello World", bạn vẫn muốn nó phù hợp với "Hello World" hoặc thậm chí là "Hello World \ n". Vì vậy, tôi chỉ thêm phương thức "trim ()" vào hàm, loại bỏ khoảng trắng xung quanh và nó bắt đầu hoạt động tốt hơn.

Đặc biệt...

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

Ngoài ra, lưu ý, câu trả lời này cực kỳ giống với Chọn liên kết theo văn bản (khớp chính xác)

Và ghi chú phụ ... trimchỉ xóa khoảng trắng trước và sau văn bản tìm kiếm. Nó không loại bỏ khoảng trắng ở giữa các từ. Tôi tin rằng đây là hành vi mong muốn, nhưng bạn có thể thay đổi điều đó nếu bạn muốn.


5

Tôi tìm thấy một cách làm việc cho tôi. Nó không chính xác 100% nhưng nó loại bỏ tất cả các chuỗi chứa nhiều hơn chỉ từ tôi đang tìm kiếm vì tôi cũng kiểm tra chuỗi không chứa các khoảng trắng riêng lẻ. Bằng cách này, bạn không cần những "". jQuery biết bạn đang tìm kiếm một chuỗi. Hãy chắc chắn rằng bạn chỉ có một khoảng trắng trong phần: chứa () nếu không nó sẽ không hoạt động.

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

Và vâng tôi biết nó sẽ không hoạt động nếu bạn có những thứ như <p>helloworld</p>


1
Sử dụng thông minh các kết hợp đơn giản với chứa (..) mà không cần sử dụng bộ lọc hoặc tiện ích mở rộng! Không làm việc trên bất cứ thứ gì cần khoảng trắng trong phần đầu tiên chứa (..), nhưng cố gắng đưa ra giải pháp cho điều đó. Cảm ơn!
JoePC

3

Giống như TJ Crowder đã nêu ở trên, chức năng lọc làm nên điều kỳ diệu. Nó đã không làm việc cho tôi trong trường hợp cụ thể của tôi. Tôi cần tìm kiếm nhiều bảng và các thẻ td tương ứng của chúng bên trong div (trong trường hợp này là hộp thoại 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.
    }
});

Tôi hy vọng điều này hữu ích cho ai đó!


Tôi khá mới đối với jquery, nhưng sẽ nghĩ rằng sẽ tốt hơn một chút khi sử dụng từng () thay vì bộ lọc () vì mục tiêu của bộ lọc là trả về một phân đoạn. Nhưng chắc chắn đã truyền cảm hứng cho giải pháp, vì tôi có cùng một vấn đề :)
JeopardyTempest

0

Một lớp lót hoạt động với các thư viện thay thế cho jQuery:

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

Và điều này tương đương với a:contains("pattern")bộ chọn của jQuery :

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

-4

.First () sẽ giúp ở đây

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

Chắc chắn ... trong trường hợp cụ thể này. Điều gì xảy ra nếu đơn hàng không được biết đến tại thời điểm dev?
BLSully
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.