Chọn phần tử theo thuộc tính dữ liệu


1020

Có một phương pháp dễ dàng và đơn giản để chọn các yếu tố dựa trên datathuộc tính của chúng không? Ví dụ: chọn tất cả các neo có thuộc tính dữ liệu có tên là customerIDgiá trị 22.

Tôi do dự khi sử dụng relhoặc các thuộc tính khác để lưu trữ thông tin đó, nhưng tôi thấy khó khăn hơn nhiều khi chọn một yếu tố dựa trên dữ liệu nào được lưu trữ trong đó.



Đó 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-customerID]')Bạn có thể sử dụng nó với ví dụ$('*[data-customerID]').each( function() { ... });
Kai Noack

Câu trả lời:


1469
$('*[data-customerID="22"]');

Bạn có thể bỏ qua *, nhưng nếu tôi nhớ chính xác, tùy thuộc vào phiên bản jQuery nào bạn đang sử dụng, điều này có thể cho kết quả bị lỗi.

Lưu ý rằng để tương thích với Selector API ( document.querySelector{,all}), các trích dẫn xung quanh giá trị thuộc tính ( 22) có thể không được bỏ qua trong trường hợp này .

Ngoài ra, nếu bạn làm việc với các thuộc tính dữ liệu rất nhiều trong các tập lệnh jQuery của mình, bạn có thể muốn xem xét sử dụng plugin thuộc tính dữ liệu tùy chỉnh HTML5 . Điều này cho phép bạn viết mã thậm chí dễ đọc hơn bằng cách sử dụng .dataAttr('foo')và dẫn đến kích thước tệp nhỏ hơn sau khi thu nhỏ (so với sử dụng .attr('data-foo')).


69
Chỉ cần một lưu ý rằng .data ('foo') hoạt động để lấy giá trị của thuộc tính 'data-foo' kể từ jQuery 1.4.3. Ngoài ra, vì jQuery 1.6: .data ('fooBar') có thuộc tính 'data-foo-bar'.
James McCormack

4
@Zootius: Vâng, plugin readme có một lưu ý về nó: Đây là jQuery 1.4.3, .data()ánh xạ tới các data-*thuộc tính tùy chỉnh theo mặc định, khiến plugin này trở nên dư thừa. Nó vẫn có thể được sử dụng cho các phiên bản cũ hơn của jQuery.
Mathias Bynens

Vậy làm thế nào để một bài viết jQuery 1.4.3, chọn một đối tượng theo giá trị của đối tượng dữ liệu của nó? Cho phép II muốn chọn trong ví dụ này, bất kỳ đối tượng nào có dữ liệu cho ID khách hàng bằng 22?
Chuyến đi

54
Ngoài ra nếu bạn chỉ quan tâm đến sự hiện diện của thuộc tính dữ liệu cụ thể, bạn có thể làm điều này:$('[data-customerID]')
Darkside

7
Điều này không hoạt động, nếu trường dữ liệu được đặt bởi jquery (sử dụng .data()), phải không?
Martin R.

329

Dành cho mọi người Google và muốn các quy tắc chung hơn về việc chọn với các thuộc tính dữ liệu:

$("[data-test]")sẽ chọn bất kỳ phần tử nào chỉ thuộc tính dữ liệu (bất kể giá trị của thuộc tính). Kể cả:

<div data-test=value>attributes with values</div>
<div data-test>attributes without values</div>

$('[data-test~="foo"]')sẽ chọn bất kỳ phần tử nào chứa thuộc tính dữ liệu foonhưng không chính xác, chẳng hạn như:

<div data-test="foo">Exact Matches</div>
<div data-test="this has the word foo">Where the Attribute merely contains "foo"</div>

$('[data-test="the_exact_value"]')sẽ chọn bất kỳ phần tử nào có giá trị chính xác của thuộc tính dữ liệu the_exact_value, ví dụ:

<div data-test="the_exact_value">Exact Matches</div>

nhưng không

<div data-test="the_exact_value foo">This won't match</div>

21
Tốt Lưu ý rằng ~=khớp với các từ được phân tách bằng khoảng trắng trong khi *=khớp với bất kỳ chuỗi con nào.
sam

Còn ^nhân vật thì sao?
kuba44

1
@ kuba44 thực sự bạn cũng có thể sử dụng ^, như vậy $('[data-test^=foo]')trong trường hợp này bạn chọn bất cứ thứ gì bắt đầu bằng foo, chẳng hạn <div data-test="foo_exact_value">hoặc <div data-test="food">không<div data-test="seafoo">
JDuarteDJ

Danh sách đầy đủ các công cụ chọn thuộc tính: dự thảo.csswg.org/selector
user1460043

142

Sử dụng $('[data-whatever="myvalue"]')sẽ chọn bất cứ thứ gì có thuộc tính html, nhưng trong jQueries mới hơn, dường như nếu bạn sử dụng $(...).data(...)để đính kèm dữ liệu, nó sử dụng một số trình duyệt ma thuật và không ảnh hưởng đến html, do đó không được phát hiện .findtrong câu trả lời trước .

Xác minh (đã thử nghiệm với 1.7.2+) (cũng xem fiddle ): (được cập nhật để hoàn thiện hơn)

var $container = $('<div><div id="item1"/><div id="item2"/></div>');

// add html attribute
var $item1 = $('#item1').attr('data-generated', true);

// add as data
var $item2 = $('#item2').data('generated', true);

// create item, add data attribute via jquery
var $item3 = $('<div />', {id: 'item3', data: { generated: 'true' }, text: 'Item 3' });
$container.append($item3);

// create item, "manually" add data attribute
var $item4 = $('<div id="item4" data-generated="true">Item 4</div>');
$container.append($item4);

// only returns $item1 and $item4
var $result = $container.find('[data-generated="true"]');

1
aha - hóa ra người khác chỉ ra điều này tại stackoverflow.com/questions/4191386/
Khăn

4
và đưa ra giải pháp .filter tại đây
drzaus

22
nó sử dụng một số trình duyệt ma thuật và không ảnh hưởng đến html : không có thứ gọi là ma thuật;) learningjquery.com/2011/09/USE-jquerys-data-apis
Tom Sarduy


1
Nếu bạn đang thêm một thuộc tính dữ liệu mà bạn cần tìm sau này, hãy sử dụng$item.attr('data-id', 10);
Pedro Moreira


68

Để chọn tất cả các neo với thuộc tính dữ liệu data-customerID==22, bạn nên bao gồm ađể giới hạn phạm vi tìm kiếm chỉ loại phần tử đó. Thực hiện tìm kiếm thuộc tính dữ liệu trong một vòng lặp lớn hoặc ở tần số cao khi có nhiều yếu tố trên trang có thể gây ra vấn đề về hiệu suất.

$('a[data-customerID="22"]');

27

Ví dụ về JS gốc

Nhận NodeList của các phần tử

var elem = document.querySelectorAll('[data-id="container"]')

html: <div data-id="container"></div>

Lấy phần tử đầu tiên

var firstElem = document.querySelector('[id="container"]')

html: <div id="container"></div>

Nhắm mục tiêu một tập hợp các nút trả về một nút

document.getElementById('footer').querySelectorAll('[data-id]')

html:

<div class="footer">
    <div data-id="12"></div>
    <div data-id="22"></div>
</div>

Nhận các phần tử dựa trên nhiều giá trị dữ liệu (OR)

document.querySelectorAll('[data-section="12"],[data-selection="20"]')

html:

<div data-selection="20"></div>
<div data-section="12"></div>

Nhận các phần tử dựa trên giá trị dữ liệu kết hợp (AND)

document.querySelectorAll('[data-prop1="12"][data-prop2="20"]')

html:

<div data-prop1="12" data-prop2="20"></div>

Nhận các mục trong đó giá trị bắt đầu bằng

document.querySelectorAll('[href^="https://"]')

Công cụ chọn "lấy phần tử đầu tiên" là chính xác nhưng không phù hợp với các ví dụ khác - tôi tin rằng nó thiếu "dữ liệu".
GuyPaddock

15

thông qua phương thức Jquery filter ():

http://jsfiddle.net/9n4e1agn/1/

HTML:

<button   data-id='1'>One</button>
<button   data-id='2'>Two</button>

JavaScript:

$(function() {    
    $('button').filter(function(){
        return $(this).data("id")   == 2}).css({background:'red'});  
     });

Bạn đã thử fiddle? Phương pháp FIlter chỉ là một cách tiếp cận khác để đạt được điều tương tự. Nó có thể hữu ích khi bạn đã có một bộ các đối tượng Jquery và bạn cần lọc dựa trên thuộc tính dữ liệu hoặc bất cứ thứ gì khác.
Razan Paul

Tôi xin lỗi, @Blizzard. Tôi đã nhận xét về câu trả lời sai. Dán nó vào bên phải bây giờ. #AlwaysALongDayAtWork
Peter Giám mục

15

Cấu trúc như thế này: $('[data-XXX=111]')không hoạt động trong Safari 8.0 .

Nếu bạn đặt thuộc tính dữ liệu theo cách này : $('div').data('XXX', 111), nó chỉ hoạt động nếu bạn đặt thuộc tính dữ liệu trực tiếp trong DOM như thế này : $('div').attr('data-XXX', 111).

Tôi nghĩ đó là vì nhóm jQuery đã tối ưu hóa trình thu gom rác để ngăn chặn rò rỉ bộ nhớ và các hoạt động nặng nề khi xây dựng lại DOM trên mỗi thuộc tính dữ liệu thay đổi.


Điều này giúp tôi rất nhiều - nếu tôi sử dụng dữ liệu hoặc phương thức prop, thì việc chọn $ ('... [data-x = "y"]') không hoạt động - thay vào đó tôi đã sử dụng attr (nó thay đổi thuộc tính DOM). Thx
Jarda

13

Để điều này hoạt động trong Chrome, giá trị không được có một cặp dấu ngoặc kép khác.

Nó chỉ hoạt động, ví dụ, như thế này:

$('a[data-customerID=22]');

4
Điều này dường như là không chính xác. Ít nhất là bây giờ không đúng. Tôi vừa mới sử dụng $ ('[data-action = "setStatus"]'). RemoveClass ('bị vô hiệu hóa'); trong Chrome và nó hoạt động hoàn hảo.
Peter Giám mục

Tôi đoán không có việc sử dụng "" bên trong bộ chọn, nó có thể được sử dụng như$('[data-action=setStatus]').removeClass('disabled')
Animesh Singh

6

Đôi khi, mong muốn lọc các phần tử dựa trên việc chúng có các mục dữ liệu được đính kèm theo lập trình hay không (hay không thông qua các thuộc tính dom):

$el.filter(function(i, x) { return $(x).data('foo-bar'); }).doSomething();

Các tác phẩm trên nhưng không dễ đọc lắm. Một cách tiếp cận tốt hơn là sử dụng bộ chọn giả để kiểm tra loại điều này:

$.expr[":"].hasData = $.expr.createPseudo(function (arg) {
    return function (domEl) {
        var $el = $(domEl);
        return $el.is("[" + ((arg.startsWith("data-") ? "" : "data-") + arg) + "]") || typeof ($el.data(arg)) !== "undefined";
    };
});

Bây giờ chúng ta có thể cấu trúc lại câu lệnh gốc thành một thứ gì đó trôi chảy và dễ đọc hơn:

$el.filter(":hasData('foo-bar')").doSomething();

1
Giải pháp đầu tiên bỏ lỡ câu lệnh return, nó cần phải là: $ el.filter (function (i, x) {return $ (x) .data ('foo-bar');}). DoS Something ();
Salma Gomaa

3

Chỉ cần hoàn thành tất cả các câu trả lời với một số tính năng của 'mức sống' - Đến bây giờ (trong thời đại html5), có thể thực hiện mà không cần libs của bên thứ 3:

  • JS thuần / đơn giản với querySelector (sử dụng bộ chọn CSS):
    • chọn cái đầu tiên trong DOM: document.querySelector('[data-answer="42"],[type="submit"]')
    • chọn tất cả trong DOM: document.querySelectorAll('[data-answer="42"],[type="submit"]')
  • CSS thuần túy / thuần túy
    • một số thẻ cụ thể: [data-answer="42"],[type="submit"]
    • tất cả các thẻ có thuộc tính cụ thể: [data-answer]hoặcinput[type]
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.