Phần tử lọc dựa trên khóa / giá trị .data ()


115

Giả sử tôi có 4 phần tử div với lớp .navlink, khi được nhấp, sử dụng .data()để đặt khóa được gọi 'selected', thành giá trị true:

$('.navlink')click(function() { $(this).data('selected', true); })

Mỗi lần .navlinknhấp chuột mới, tôi muốn lưu trữ các lựa chọn trước đó navlinkđể thao tác sau này. Có cách nào nhanh chóng và dễ dàng để chọn một yếu tố dựa trên những gì được lưu trữ bằng cách sử dụng .data()không?

Dường như không có bất kỳ bộ lọc jQuery nào : phù hợp với hóa đơn và tôi đã thử các cách sau (trong cùng một sự kiện nhấp chuột), nhưng vì một số lý do, nó không hoạt động:

var $previous = $('.navlink').filter( 
    function() { $(this).data("selected") == true }
);

Tôi biết rằng có nhiều cách khác để thực hiện điều này, nhưng hiện tại tôi hầu như chỉ tò mò liệu nó có thể được thực hiện thông qua .data().

Câu trả lời:


191

bộ lọc của bạn sẽ hoạt động, nhưng bạn cần trả về true trên các đối tượng phù hợp trong hàm được truyền cho bộ lọc để lấy chúng.

var $previous = $('.navlink').filter(function() { 
  return $(this).data("selected") == true 
});

6
Xin lưu ý rằng đây không còn là cách duy nhất để thực hiện việc này, StefanoP đã cung cấp giải pháp thay thế
Nathan Koop

3
@NathanKoop, không hẳn. Xem bình luận của tôi về câu trả lời của anh ấy.
Bryan Downing

Đối với những người sử dụng thuộc tính dữ liệu để tìm một yếu tố không thể bắt buộc khác (id ít div hơn, v.v ... mà bạn cần có thể truy cập vì bất kỳ lý do gì) tại bất kỳ vị trí nào trong tài liệu:$("*").filter(function() { return $(this).data("DATA IDENTIFIER HERE") == DATA VALUE HERE; });
Tschallacka

đây không phải là "lộn xộn" - đây là cách lọc an toàn duy nhất theo các thuật ngữ tùy ý mà không yêu cầu bạn "thoát" các giá trị đó để đảm bảo rằng việc kết hợp thuật ngữ tìm kiếm với phần còn lại của bộ chọn không tạo ra bộ chọn bất hợp pháp.
Alnitak

145

Chỉ để ghi lại, bạn có thể lọc dữ liệu bằng jquery (câu hỏi này khá cũ và jQuery đã phát triển kể từ đó, vì vậy cũng đúng khi viết giải pháp này):

$('.navlink[data-selected="true"]');

hoặc, tốt hơn (cho hiệu suất):

$('.navlink').filter('[data-selected="true"]');

hoặc, nếu bạn muốn lấy tất cả các thành phần với data-selectedtập hợp:

$('[data-selected]')

Lưu ý rằng phương pháp này sẽ chỉ hoạt động với dữ liệu được đặt thông qua các thuộc tính html. Nếu bạn đặt hoặc thay đổi dữ liệu với .data()cuộc gọi, phương thức này sẽ không còn hoạt động.


9
nếu số phiếu thấp cho câu trả lời này làm bạn sợ - đó là câu trả lời được chấp nhận với hơn 100 phiếu cho một câu hỏi stackoverflow.com/questions/4146502
Simon_Weaver

47
-1 Điều này không hoạt động khi dữ liệu được đặt bằng .data()phương thức thay vì data-thuộc tính. Xem fiddle này: jsfiddle.net/bryandowning/tySWC - Ngoài ra, .find()phương pháp tìm kiếm con của bộ chọn trước. Trong ví dụ đã cho, data-selectedlà một thuộc tính của .navlink, không phải là con của .navlink. Ngoài ra, $('div p')$('div').find('p')về cơ bản là tương đương. Việc sử dụng .find()có vẻ như có thể chậm hơn do cuộc gọi chức năng bổ sung (mặc dù tôi không tích cực về việc này). Vui lòng sửa cho tôi nếu tôi sai về bất kỳ điều nào trong số này (tôi thực sự muốn phương pháp này hiệu quả).
Bryan Downing

3
một vài điều: 1) bạn đúng rằng điều này không hoạt động nếu bạn đặt dữ liệu .data(), vì jQuery tìm kiếm thông qua DOM, tôi đã đăng nó cho những người (như tôi), người đã đặt câu hỏi này vì những lý do khác; 2) chính xác, .find()tìm kiếm thông qua trẻ em, vì vậy nó sai trong ví dụ này; 3) bạn sai, chúng không tương đương, khi jQuery tìm kiếm từ phải sang trái, xem jonraasch.com/blog/ Kẻ
StefanoP

2
Bỏ phiếu cho $('[data-selected]')nó đã giúp tôi hiểu điều gì đó như$('ul.categories a[data-categories_id]').click(......);
Luke Cousins

Ngoài ra, có vẻ như nếu bạn cập nhật thuộc tính dữ liệu bằng .attr, nếu bạn truy xuất nó bằng .data, giá trị sẽ không được cập nhật - vì vậy hãy cẩn thận khi trộn hai
Fabio Lolli

13

Chúng tôi có thể tạo một plugin khá dễ dàng:

$.fn.filterData = function(key, value) {
    return this.filter(function() {
        return $(this).data(key) == value;
    });
};

Cách sử dụng (kiểm tra nút radio):

$('input[name=location_id]').filterData('my-data','data-val').prop('checked',true);

Bạn có nghĩa là phương pháp plugin nếu không, đây giống như câu trả lời được chấp nhận ...
jave.web

@ jave.web Thật vậy. Nhưng không phải ai cũng biết cách biến nó thành một plugin. Cập nhật thông báo.
mở

đừng hiểu sai ý tôi, câu trả lời của bạn rất hay, tuy nhiên những từ ở đây rất quan trọng, cảm ơn bạn đã cập nhật :)
jave.web

8

Hai điều tôi nhận thấy (chúng có thể là những sai lầm từ khi bạn viết nó xuống).

  1. Bạn đã bỏ lỡ một dấu chấm trong ví dụ đầu tiên ( $('.navlink').click)
  2. Để bộ lọc hoạt động, bạn phải trả về giá trị ( return $(this).data("selected")==true)

-1

Âm thanh như công việc nhiều hơn giá trị của nó.

1) Tại sao không chỉ có một biến JavaScript duy nhất lưu trữ một tham chiếu đến đối tượng phần tử \ jQuery hiện được chọn.

2) Tại sao không thêm một lớp vào thành phần hiện được chọn. Sau đó, bạn có thể truy vấn DOM cho lớp ".active" hoặc một cái gì đó.


Vâng, nhưng như tôi đã nói, tôi biết có nhiều cách khác để hoàn thành nó. Tôi chỉ băn khoăn liệu nó có thể được lọc qua dữ liệu () hay không và tại sao bộ lọc () không hoạt động với tôi. Cảm ơn mặc dù.
dùng113716

Lấy làm tiếc. Tôi đã bỏ lỡ một phần câu hỏi của bạn.
Bryan Migliorisi
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.