29/09/2011 10:03:04 AMThiết kế web nâng cao với jquery phần 2
(Lượt xem: 4204)Thư viện jQuery tận dụng kiến thức và thế mạnh của CSS Selector để cho phép bạn nhanh chóng và dễ dàng truy cập nhiều phần tử hoặc nhóm các phần tử trong DOM (Document Object Model).Bây giờ bạn có thể thêm style vào stylesheet cho tất cả các dòng của bảng và sử dụng một class=’alt’ cho những dòng chẵn.
.alt {
background: #dda;
}
td {
padding: 10px;
}
Cuối cùng chúng ta sẽ viết code jQuery để gắn class vào cho những dòng chẵn của bảng (
).
1.$(document).ready(function() {
2.
$('tr:0dd').addClass('alt');
3.
});
Bạn có thấy code ở trên có điều gì lạ không? Odd tiếng Việt là lẻ và
Even là chẵn. Chúng ta nói sẽ tô màu cho dòng chẵn nhưng lại sử dụng
:0dd? Thực ra vấn đề ở đây cũng tương tự như :eq() ở trên, bởi vì :0dd
và :even sử dụng dạng đánh số từ số 0 như trong JavaScript. Cho nên dòng
thứ nhất đếm là số 0 (số chẵn) và dòng thứ hai đếm là 1 (số lẻ). Do đó
với dòng code jQuery như trên dưới đây là kết quả chúng ta có được.
Vấn đề có vẻ như đã được giải quyết ở đây, nhưng nếu bạn có một bảng
thứ hai trên cùng một trang thì kết quả lại không như bạn muốn. Ví dụ,
dòng cuối cùng của bảng trên có màu cỏ úa thì dòng đầu tiên của bảng kế
tiếp sẽ có màu trắng. Có cách để tránh tình trạng này là sử dụng
:nth-child() Selector. Selector này có thể lấy tham số là odd, even hoặc
chữ số. Nhưng cũng lưu ý bạn là :nth-child() là selector duy nhất của
jQuery đánh số theo thứ tự từ 1. Cho nên để đạt được kết quả như mong
muốn và nhất quán với nhiều bảng trên trang, chúng ta có đoạn code mới
như sau:
1.$(document).ready(function() {
2.$('tr:nth-child(even)').addClass('alt');
3.});
Bây giờ giả sử chúng ta muốn tô đậm đỏ cho cột nào đó có chưa tên chú
Bruce Willis thì trước hết bạn phải thêm một class=’red’ vào phần
stylesheet và sau đó thì viết code jQuery như sau sử dụng :contains() Selector.
1.$(document).ready(function() {
2.$('tr:nth-child(even)').addClass('alt');
3.$('td:contains(Bruce Willis)').addClass('red');
4.});
Bây giờ thì bảng của chúng ta đã tô đậm và in đỏ chú Bruce Willis.
Tôi cũng phải lưu ý với bạn là :contains() Selector có phân biệt giữa IN HOA và in thường. Cho nên nếu bạn chỉ gõ $(‘td:contains(bruce willis)’) mà không viết hoa thì sẽ không có cột nào được chọn cả.
Phải thừa nhận rằng với ví dụ đơn giản như trên, bạn không cần phải
sử dụng jQuery cũng đạt được kết quả như mong muốn. Tuy nhiên, jQuery
kết vợi với CSS, là một lựa chọn phù hợp cho kiểu định dạng khi mà nội
dung được tạo ra tự động từ CSDL và chúng ta không có khả năng chi phối
code HTML cũng như code được xuất ra từ PHP chẳng hạn.
Form Selector
Khi làm việc với form, những selector của jQuery giúp bạn tiết kiệm
thời gian để chọn chỉ những thành phần nào mình muốn. Bảng biểu sau là
những selector của jQuery để làm việc với form.
Cũng giống như những Selector khác, form Selector cũng có thể được
kết hợp để cho đối tượng chọn được cụ thể hơn. Ví dụ chúng ta có thể
chọn tất cả các nút radio được đánh dấu (chứ không phải hộp kiểm) với
$(‘:radio:checked’) hoặc chọn tất cả các trường nhập mật khẩu và trường
nhập dữ liệu bị tắt với $(‘:passowrd, :text:disabled’). Cho dù với
jQuery Selector, nhưng chúng ta vẫn sử dụng nguyên tắc của CSS để chọn
các phần tử cần chọn.
Phương pháp di chuyển trong DOM
Những jQuery selector vừa được giới thiệu ở trên cho phép chúng ta
chọn một tập hợp các phần tử khi chúng ta di chuyển ngang qua hoặc dọc
xuống cây DOM và chọn lọc kết quả. Nếu đây là cách duy nhất để chọn các
phần tử thì những lựa chọn của chúng ta cũng bị hạn chế khá nhiều (mặc
dù trong thực tế những selector đã rất mạnh mẽ đặc biệt là khi mang ra
so sánh với cách di chuyển trong DOM truyền thống). Có nhiều trường hợp
khi bạn cần phải chọn cha mẹ hoặc ông bà của các phần tử trở nên quan
trọng, chính vì vậy phương pháp di chuyển trong DOM được giới thiệu. Với
những phương pháp này chúng ta có thể đi lên, đi xuống, ngang dọc hoặc
xung quanh cây DOM rất dễ dàng.
Một vài phương pháp có chức năng gần như tương đồng với những người
‘anh em’ Selector ở trên. Như trong ví dụ về định dạng bảng kiểu kẻ sọc ở
trên chúng ta thêm class=’alt’ với $(‘tr:0dd’).addClass(‘alt’); cũng có
thể được viết lại với phương pháp .filter() như sau:
1.$('tr').filter(':0dd').addClass('alt');
Trong đa số các trường hợp thì hai cách trên bổ trợ cho nhau. Hơn nữa, đặc biệt là phương pháp .filter()
cực kỳ mạnh mẽ ở chỗ nó có thể lấy một hàm làm tham số của nó. Hàm đó
cho phép chúng ta tạo ra những phép kiểm phức tạp để xác định xem một
thành phần nào đó có nên được giữ lại trong tập hợp kết quả trả về. Nói
ví dụ chúng ta muốn thêm một class cho tất cả những đường liên kết
ngoài. Jquery không có selector nào có thể tiến hành tác vụ này. Nếu
không có hàm trong phương pháp .filter(),
chúng ta bắt buộc phải sử dụng vòng lặp để nhảy qua từng thành phần và
kiểm tra nó riêng rẽ. Tuy nhiên với những hàm trong phương pháp .filter() sau, chúng ta vẫn có thể dựa vào vòng lặp ẩn của jQuery và giữ cho code của chúng ta gọn gàng.
1.$('a').filter(function() {
2.return this.hostname && this.hostname != location.hostname;
3.}).addClass('external');
Dòng code thứ 2 lọc tập hợp các phần tử <a> với hai tiêu chí sau:
1.Nó phải có thuộc tính href với tên miền (this.hostname). Chúng ta sử
dụng phép kiểm này để loại bỏ những liên kết dạng mailto và những thứ
tương tự.
2.Tên miền mà nó liên kết tới (this.hostname) không được giống (!=) với tên miền của trang hiện tại (location.hostname).
Nói chính xác hơn thì phương pháp .filter() lặp qua tập hợp những
phần tử phù hợp, kiểm tra từng giá trị trả về bằng hàm đã tạo. Nếu hàm
trả về là false, thì phần tử đó sẽ bị loại khỏi tập hợp. Còn nếu giá trị
trả về là true, thì phần tử đó được giữ lại. Bây giờ chúng ta sẽ xem
lại bảng kiểu kẻ sọc và xem xem có thể làm gì với phương pháp di chuyển
này.
Định dạng từng ô cụ thể
Ở ví dụ trên chúng ta đã thêm class=’red’ cho những ô có chữa chữ
Bruce Willis. Nếu bây giờ chúng ta cũng muốn định dạng cho ô bên cạnh ô
chứa Bruce Willis, chúng ta có thể bắt đầu với Selector mà chúng ta đã
tạo, và sau đó chỉ đơn giản nối nó với phương pháp .next().
1.$(document).ready(function() {
2.$('td:contains(Bruce Wiliss)').next().addClass('red');
3.});
Bảng của bạn sẽ được như sau
Phương pháp .next() chỉ lựa chọn các phần tử ngay sát cạnh nó. Để tô
đỏ đậm cho tất cả các ô đằng sau ô có chưa Bruce Willis, chúng ta có thể
sử dụng phương pháp .nextAll().
1.$(document).ready(function() {
2.$('td:contains(Bruce Wiliss)').nextAll().addClass('red');
3.});
Bên cạnh phương pháp .next() và .nextAll() chúng ta còn có .prev() và
prevAll(). Thêm nữa, .siblings() chọn tất cả các phần tử có cùng chung
một cấp bậc trên DOM, mà không cần quan tâm đến nó xuất hiện trước hoặc
sau phần từ được chọn.
Để bao gồm cả ô ban đầu (là ô có chữa Bruce Willis) và những ô theo sau nó, chúng ta có thể thêm phương pháp .andSelf():
1.$(document).ready(function() {
2.$('td:contains(Bruce Wiliss)').nextAll().andSelf().addClass('red');
3.});
Bạn cũng nên biết rằng có vố số những kết hợp của selector và phương
pháp di chuyển mà dựa vào đó chúng ta có thể chọn cùng một tập hợp các
phần tử. Ví dụ này sẽ cho bạn thấy một cách khác để chọn mỗi một ô trong
một dòng mà ô đó có chưa chữ Bruce Willis:
1.$(document).ready(function() {
2.
$('td:contains(Bruce Willis)').parent().children().addClass('red');
3.
});
Ở đây thay vì chúng ta di chuyển theo kiểu ngang hàng, chúng ta di chuyển lên trên một bậc của cây DOM (
) với phương pháp .parent() và sau đó chọn tất cả các ô của dòng bằng phương pháp .children().
Kết hợp (chaining)
Phương pháp di chuyển kết hợp như chúng ta vừa khám phá ở trên thể
hiện khả năng kết hợp của jQuery. Với jQuery bạn có thể chọn tập hợp các
phần tử và thao tác nhiều tác vụ lên chúng, tất cả trên cùng một dòng
code. Kiểu kết hợp này không những giữ cho code jQuery được súc tích mà
còn tăng khả năng hoạt động của mã. Nhưng để cho dễ đọc hơn, bạn cũng có
thể tách ra thành nhiều hàng. Ví dụ một dãy kết hợp các phương pháp có
thể được viết trên một dòng như sau:
1.$('td:contains(Bruce Willis)').parent().find('td:eq(1)').addClass('red').end().find('td:eq(2)').addClass('red');
… hoặc cắt nhỏ ra từng dòng
1$('td:contains(Bruce Willis)') // Tìm tất cả các dòng có chứa Bruce Willis
2.parent() // Di chuyển lên một tầng
3.find('td:eq(1)') // Tìm td với thứ tự là 1 (dòng thứ 2)
4.addClass('red') // Thêm class='red'
5.end() // quay về với bố mẹ của ô chứa Henry
6.find('td:eq(2)') // Tìm tiếp td với thứ tự là 2 (dòng 3)
7.addClass('red') // thêm class='red'
Tất nhiên cách di chuyển kiểu như trên là lòng vòng đến mức thừa thãi và
không có trong thực tế. Bởi vì có nhiều cách khác đơn giản hơn, trực
tiếp hơn. Tuy nhiên nó cũng cho bạn thấy được sự linh hoạt tuyệt vời mà
kiểu kết hợp cho phép chúng ta.
Viết code kiểu kết hợp thế này như là nói một tràng trong một hơi không
nghỉ. Nó giúp bạn đạt mục tiêu nhanh chóng, nhưng lại khó cho người khác
hiểu được. Cho nên tách nó ra và thêm comments có thể giúp bạn tiết
kiệm thời gian và công sức sau này nếu phải chỉnh sửa code.
Hướng tới các thành phần DOM
Mỗi một Selector và hầu hết các phương pháp của jQuery đều trả về một
đối tượng jQuery. Đây chính là điều chúng ta luôn mong đợi, bởi vì khả
năng tiến hành vòng lặp ẩn và kết hợp nó có thể làm. Nhưng cũng có lúc
chúng ta muốn hướng tới một phần tử DOM một cách trực tiếp. Ví dụ, chúng
ta muốn sử dụng một tập hợp các phần tử cho một thư viện JavaScript
khác. Hoặc chúng ta muốn hướng tới tên thẻ của một phần tử, mà nó lại có
sẵn như là một thuộc tính của phần tử DOM. Tuy trường hợp này hiếm khi
xảy ra, jQuery có phương pháp .get(). Để hướng tới thành phần DOM đầu
tiên chỉ đến bởi một đối tượng jQuery, chúng ta sẽ sử dụng .get(0). Nếu
phần tử DOM cần phải nằm trong một vòng lặp, chúng ta sẽ sử dụng
.get(index). Như vậy, nếu chúng ta muốn biết tên thẻ của một thành phần
với id=’my-element’, chúng ta sẽ viết code như sau:
1.var myTag = $('#my-element').get(0).tagName;
Để tiện dụng hơn nữa, jQuery cung cấp cách viết tắt cho phương pháp
.get(). Thay vì viết như dòng code ở trên, chúng ta có thể sử dụng cặp
ngoặc vuông [] ngay đằng sau selector:
1.var myTag = $('#my-element')[0].tagName;
Không phải là ngẫu nhiên mà cú pháp này nhìn giống như là một array
của các phân tử DOM, sử dụng cặp ngoặc vuông như là xé đi lớp vỏ để tới
danh sách các nốt, có bao gồm luôn cả index (trong trường hợp này là 0)
cũng giống như lôi từng thành phần DOM ra vậy.
Kết luận
Với những kỹ năng mà chúng ta đã học trong chương này, chúng ta đã có
thể định dạng cho tầng một và tầng phụ của một danh sách sử dụng những
CSS Selector cơ bản, áp dụng những style khác nhau cho các loại đường
liên kết khác nhau sử dụng Attribute Selector, tô mầu khác nhau cho bảng
kẻ sọc bằng cách sử dụng jQuery selector như :0dd và :even hoặc
Selector mới của CSS là :nth-child(), và
cuối cùng là tô đậm đỏ cho từng ô trong bảng bằng cách kết hợp các
phương pháp jQuery. Cho đến bây giờ chúng ta sử dụng sự kiện $(document).ready()
để thêm class vào tập hợp các phần tử. Trong chương tới, chúng ta sẽ
khám phá những cách để thêm class vào những sự kiện người dùng tự tạo.