jQuery làm thế nào để tìm một phần tử dựa trên giá trị thuộc tính dữ liệu?


994

Tôi đã có kịch bản sau đây:

var el = 'li';

và có 5 <li>'trên mỗi trang có một data-slide=numberthuộc tính (số tương ứng là 1,2,3,4,5) .

Bây giờ tôi cần tìm số slide hiện đang được ánh xạ var current = $('ul').data(current);và được cập nhật trên mỗi thay đổi slide.

Cho đến nay, những nỗ lực của tôi đã không thành công, cố gắng xây dựng bộ chọn phù hợp với slide hiện tại:

$('ul').find(el+[data-slide=+current+]);

không khớp / trả lại bất cứ thứ gì

Lý do tôi không thể mã hóa liphần đó là vì đây là biến người dùng có thể truy cập có thể được thay đổi thành một yếu tố khác nếu được yêu cầu, vì vậy nó có thể không phải luôn luôn là một li.

Bất cứ ý tưởng về những gì tôi đang thiếu?


6
Bạn có chắc .find(el+[data-slide=+current+]);là trong mã của bạn viết không? có vẻ như bạn đã bỏ lỡ một số trích dẫn đến"[data-slide]"
xandy

Đó là điều giúp tôi chọn tất cả các thuộc tính dữ liệu (bất kể giá trị): $('*[data-slide]')Bạn có thể sử dụng nó với ví dụ$('*[data-slide]').each( function() { ... });
Kai Noack

Câu trả lời:


1481

Bạn phải đưa giá trị của currentvào bộ chọn Thuộc tính bằng :

$("ul").find(`[data-slide='${current}']`)

Đối với môi trường JavaScript cũ hơn ( ES5 trở về trước):

$("ul").find("[data-slide='" + current + "']"); 

8
@Jannis, bạn có thể làm $("ul").find(el + "[data-slide='" + current +"']");.
Frédéric Hamidi

7
@ c00lryguy, jQuery UI định nghĩa một và có các triển khai độc lập xung quanh. Có vẻ như các nỗ lực để thêm nó vào jQuery Core đã bị từ chối . Hai lần .
Frédéric Hamidi

6
câu trả lời này trên một bài đăng tương tự có một ví dụ về chức năng lọc
drzaus

77
Tôi lo lắng rằng điều này sẽ không hoạt động nếu dữ liệu được thêm vào thông qua chức năng jQuery .data (...), vì điều này không phải lúc nào cũng hiển thị một thuộc tính và do đó sử dụng cơ chế lưu trữ cụ thể của trình duyệt. Một lý do khác mà tôi muốn lõi jQuery có bộ chọn dữ liệu cụ thể.
AaronLS

77
Lưu ý rằng nó không hoạt động đối với các phần tử nơi bạn đặt dữ liệu với $ ('# phần tử'). Data ('some-att-name', value); nhưng chỉ dành cho những người có thuộc tính mã hóa cứng. Tôi đã gặp vấn đề này và để làm cho nó hoạt động thiết lập dữ liệu bằng cách viết thuộc tính trực tiếp $ ('# phần tử'). Attr ('data-some-att-name', value);
Pawel

463

trong trường hợp bạn không muốn nhập tất cả, đây là một cách ngắn hơn để truy vấn theo thuộc tính dữ liệu:

$("ul[data-slide='" + current +"']");

FYI: http://james.padolsey.com/javascript/a-better-data-selector-for-jquery/


31
Đối với những người bạn quan tâm, được cung cấp cấu trúc <ul><li data-slide="item"></li></ul>, bộ chọn câu trả lời này sẽ trả về không xác định để nó không hoạt động theo kịch bản của người dùng. Câu trả lời này S work hoạt động cho cấu trúc <ul data-slide="item"><li></li></ul> Trong khi tôi hiểu tại sao sự phổ biến của nó do sự ngắn gọn, về mặt kỹ thuật nó là một câu trả lời không chính xác. jsfiddle.net/py5p2abL/1
akousmata

4
Đừng quên coi nó như một mảng. Sử dụng [0]để truy cập các yếu tố đầu tiên được tìm thấy.
Aminah Nuraini

Một hiệu ứng phụ kỳ quái ... phương pháp này hoạt động phù hợp với phần tử với thuộc tính dữ liệu khi .find("[data-attrib='value']")không hoạt động. Tôi không biết các giá trị là thuộc tính dữ liệu có được thêm bởi jQuery hay không ...
lỗi

1
Nó không kỳ quái bởi vì hai câu trả lời làm 2 việc khác nhau. $.findđặc biệt tìm thấy hậu duệ của phần tử đó, nhưng sử dụng cú pháp bộ lọc trong chuỗi bộ chọn sẽ chỉ lọc các kết quả.
Phil

227

Khi tìm kiếm với [data-x = ...], xem ra, nó không hoạt động với setter jQuery.data (..) :

$('<b data-x="1">'  ).is('[data-x=1]') // this works
> true

$('<b>').data('x', 1).is('[data-x=1]') // this doesn't
> false

$('<b>').attr('data-x', 1).is('[data-x=1]') // this is the workaround
> true

Bạn có thể sử dụng điều này thay thế:

$.fn.filterByData = function(prop, val) {
    return this.filter(
        function() { return $(this).data(prop)==val; }
    );
}

$('<b>').data('x', 1).filterByData('x', 1).length
> 1

1
sự $.fn.filterByDatarực rỡ; tuy nhiên, đây là một cảnh báo cho những người sao chép ngoài kia ... bạn chỉ cần $('<b>').filterByData('x', 1)tìm <b>các thẻ với data-x="1". nếu bạn sao chép-dán .data(x, 1)phần ... bạn sẽ đặt data-xthành "1" trước khi lọc.
WEBjuju

39

Tôi đã cải thiện khả năng mở rộng bộ lọcByData của psycho brm sang jQuery.

Trong đó tiện ích mở rộng trước đây đã tìm kiếm trên cặp khóa-giá trị, với tiện ích mở rộng này, bạn có thể tìm kiếm thêm sự hiện diện của thuộc tính dữ liệu, bất kể giá trị của nó.

(function ($) {

    $.fn.filterByData = function (prop, val) {
        var $self = this;
        if (typeof val === 'undefined') {
            return $self.filter(
                function () { return typeof $(this).data(prop) !== 'undefined'; }
            );
        }
        return $self.filter(
            function () { return $(this).data(prop) == val; }
        );
    };

})(window.jQuery);

Sử dụng:

$('<b>').data('x', 1).filterByData('x', 1).length    // output: 1
$('<b>').data('x', 1).filterByData('x').length       // output: 1

Hoặc câu đố: http://jsfiddle.net/PTqmE/46/


34

Không có JQuery, ES6

document.querySelectorAll(`[data-slide='${current}']`);

Tôi biết câu hỏi là về JQuery, nhưng người đọc có thể muốn một phương thức JS thuần túy.


33

Tôi đã gặp vấn đề tương tự trong khi tìm nạp các phần tử bằng cách sử dụng thuộc tính jQuery và data- *.

vì vậy để bạn tham khảo mã ngắn nhất ở đây:

Đây là Mã HTML của tôi:

<section data-js="carousel"></section>
<section></section>
<section></section>
<section data-js="carousel"></section>

Đây là bộ chọn jQuery của tôi:

$('section[data-js="carousel"]');
// this will return array of the section elements which has data-js="carousel" attribute.

19
$("ul").find("li[data-slide='" + current + "']");

Tôi hy vọng điều này có thể làm việc tốt hơn

cảm ơn


15

Bộ chọn $("ul [data-slide='" + current +"']");này sẽ hoạt động cho cấu trúc sau:

<ul><li data-slide="item"></li></ul>  

Trong khi điều này $("ul[data-slide='" + current +"']");sẽ làm việc cho:

<ul data-slide="item"><li></li></ul>


12

Quay trở lại câu hỏi ban đầu của anh ấy, về cách làm cho công việc này hoạt động mà không biết trước loại phần tử, sau đây thực hiện điều này:

$(ContainerNode).find(el.nodeName + "[data-slide='" + current + "']");
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.