01/10/2018, 17:21

Viết custom selectors trong JQuery

JQuery rất mạnh trong việc hỗ trợ chúng ta lấy được các element bằng cách dùng cú pháp selector và filter. Chúng ta có thể lấy được các element theo id, class, theo tag hoặc lọc theo nội dung, thuộc tính …. Ví dụ: – $(‘p’): lấy tất cả thẻ p – $(‘#abc’): lấy ...

JQuery rất mạnh trong việc hỗ trợ chúng ta lấy được các element bằng cách dùng cú pháp selector và filter. Chúng ta có thể lấy được các element theo id, class, theo tag hoặc lọc theo nội dung, thuộc tính ….

Ví dụ:

– $(‘p’): lấy tất cả thẻ p

– $(‘#abc’): lấy element có id là abc

– $(‘.test’): lấy tất cả element có class là test

– $(‘p:contains(Tôi khoái JQuery)’): lọc tất cả các thẻ có nội dung là “Tôi khoái JQuery”

– $(‘p:even’): lọc tất cả các thẻ p ở vị trí chẳn

Ngoài những gì JQuery hỗ trợ cho chúng ta, chúng ta cũng có thể viết custom selector trong JQuery để lọc các element theo ý muốn của chúng ta.

1. Cú pháp

$.expr[':'].selector_name = function(obj, index, meta, stack){
 // Mình sẽ viết code ở đây
}

Giải thích:
obj: tham chiếu đến dom element hiện tại
index: vị trí index hiện tại trong stack ở trên
meta: cất giữ thông tin về selector của chúng ta
stack: mảng các element, các element này là “thô”, chưa được lọc. Mảng các element này sẽ được lọc theo meta ở trên

2. Viết ít code để tạo custom selector đơn giản
Mình giả sử các bạn có nhiều thẻ div nằm trên document của các bạn. Các bạn chỉ muốn lọc ra những thẻ div nào có chiều rộng dài hơn 125 pixels. Chúng ta sẽ viết như sau:

 $.extend($.expr[':'], {
     wider125pixels: function(a) {
         return $(a).awidth() > 125;
     }
 });

Và sử dụng custom selector của chúng ta như sau

 $('div:wider125pixels').click(function() {
     alert('Thẻ div này dài hơn 125 pixels');
 });

Ok! Custom selectors của chúng ta đến đây có vẻ tạm ổn. Nhưng nhìn kỹ thì có vẻ chưa được linh hoạt lắm. Giả sử chúng ta không muốn lấy dài hơn 125 pixels mà là lấy dài hơn 150 pixels thì sao nhỉ? Chẳng lẽ chúng ta phải sửa lại code hay viết thêm một custom selectors khác. Chúng ta cần một cái gì đó linh hoạt hơn. Chúng ta có thể giải quyết vấn đề này bằng cách sử dụng parameters

2. Viết ít code để tạo custom selector phức tạp hơn có sử dụng parameters của meta

a. Giải thích về meta: meta là một mảng giữ thông tin về selector của chúng ta
– Mình giả sử bạn có câu lệnh sau

 $('div:widerThan(argument)');

Thì lúc đó bạn sẽ có mảng meta cất giữ những thông tin sau

[
‘:widerThan(argument)’, // Tại vị trí index 0, cất giữ thông tin đầy đủ về selector gồm tên và tham số
‘widerThan’, // Tại vị trí index 1, chỉ cất giữ thông tin về tên selector
”,// Tại vị trí 2, cất giữ thông tin về dấu quote được sử dụng
‘argument’ // Tại vị trí index 3 chỉ cất giữ các parameters
]
– Mình giả sử bạn có câu lệnh sau

 $('div:widerThan(w1, w2)');

Thì lúc đó bạn sẽ có mảng meta cất giữ những thông tin sau

[
‘:widerThan(argument)’, // Tại vị trí index 0, cất giữ thông tin đầy đủ về selector gồm tên và tham số
‘widerThan’, // Tại vị trí index 1, chỉ cất giữ thông tin về tên selector
‘”‘,// Tại vị trí 2, cất giữ thông tin về dấu quote được sử dụng
‘w1, w2’ // Tại vị trí index 3 cất giữ các tham số
]
b. Cải tiến
Bây giờ các bạn đã hiểu về meta. Các bạn sử dụng giá trị ở vị trí index thứ 3 để tăng tính linh hoạt của custom selector của chúng ta. Chúng ta sẽ cải tiến như sau:

 
$.extend($.expr[':'], {
     widerThan: function(obj, index, meta, stack) {
         return $(obj).awidth() > meta[3];
     }

Và sử dụng custom selector của chúng ta như sau

 $('div:widerThan(125)').click(function() {
     alert('Thẻ div này dài hơn 125 pixels');
 });

Ok! Đến đây, custom selector của chúng ta đã uyển chuyển hơn và dễ dùng hơn
Chúng các bạn thành công và hiểu rõ hơn về JQuery custom selector :)


0