jQuery basic: CSS Selectors

jQuery thực sự mạnh mẽ thật đúng với slogan "write less, do more", nó là một thư viện JavaScript rất giễ ràng sử dụng nó giúp các nhà thiết kế và phát triển web thêm các các phần tử có sự tương tác và có tính năng động về phía người dùng. Nếu trước kia bạn viết JavaScript mà không sử dụng thư viện thì sẽ rất dài vì bạn phải tự xây dựng thêm các hàm để chọn rồi sử lý phần tử bây giờ mọi thứ trở nên đơn giản và ngắn gọn như bạn viết CSS vậy. Bài viết này sẽ giới thiệu về các biểu thức chọn trong jQuery theo dạng CSS selector.

Element

Để chọn theo tên thẻ sử dụng cú pháp $('tên thẻ')

ID: #myid

Chọn theo tên id của phần tử sử dụng cú pháp $('tên id')

Class: .myclass

Chọn theo tên class của phần tử sử dụng cú pháp $('.tên class'). Có một điều nên chú ý rằng trong cấu trúc hồ sơ của bạn thì class thường được dùng cho nhiều phần tử nên kết quả biểu thức chọn này thường trả về một mảng phần tử.

Descendant: E F

Chọn theo con cháu ví dụ chọn phần tử img là hậu duệ của phần tử a sẽ có cú pháp $('a img')

Child: E > F

Chọn theo thẻ con trực tiếp cú pháp $('tên thẻ > tên thẻ'). Phương pháp chon theo CSS này được hổ trợ trên hầu hết các trình duyệt hiện đại và không hổ trợ trên trình duyệt IE từ phiên bản 6 về trước

Adjacent Sibling: E + F

Chọn những thẻ có cùng phần tử cha và nằm kế nhau tức chúng là anh em của nhau, cú pháp $('tên thẻ + tên thẻ')

General Sibling: E ~ F

Chọn những phần tử F cùng cấp với phần tử E, cú pháp $('tên thẻ ~ tên thẻ')

Multiple Elements: E,F,G

Chọn nhiều phần tử cùng lúc, cú pháp $('tên thẻ, tên thẻ,...')

Nth Child (:nth-child(n))

Chọn phần tử con theo thứ tự chỉ mục n, ở đây nth-child(n) sẽ đánh số từ 1 và đánh chỉ mục với tất cả các thẻ con, trong khi đó nth(n) sẽ đánh số từ 0 và chỉ đánh chỉ mục theo phần tử bạn chọn. Ngoài ra bạn có thể thay n bằng từ khóa even để chọn những phần tử con chẵn hoặc odd để chọn những phần tử con lẻ.

First Child (:first-child)

Chọn phần tử con đầu tiên, cú pháp $('tên thẻ:first-child')

Last Child (:last-child)

Chọn phần tử con cuối cùng, cú pháp $('tên thẻ:last-child')

Only Child :only-child

Chọn tất cả những phần tử chỉ là con, cú pháp $('tên thẻ:only-child')

Not :not(s)

Chọn theo dạng phủ định. Ví dụ

  • $('li:not(.myclass)') Chọn những phần tử li nào không có class tên myclass
  • $('li:not(:last-child)') Chọn những phần tử  li nào không phải là phần tử con cuối cùng

Empty :empty

Chọn những phần tử nào rỗng tức là nó không có con cháu, cú pháp $('phần tử:empty') hoặc $(':empty')

Universal: *

Dấu * sử dụng trong thẻ chọn đại diện cho tất cả các phần tử

Trong những bài viết tiếp theo sẽ giới thiệu về những phương pháp chọn phần tử tiếp theo.

Tham khảo (jQuery Reference Guide and docs.jquery.com)

jQuery basic: Attribute Selectors, Custom Selectors

Bài viết này sẽ giới thiệu cách chọn phần tử theo thuộc tính và giựa theo các tùy chọn về vị trí của phần tử.

Attribute Selectors

Has Attribute: [foo]

Chọn các phần tử có thuộc tính là foo

Attribute Value Equals: [foo=bar]

Chọn các phần tử có thuộc tính foo với giá trị bằng bar

Attribute Value Does Not Equal: [foo!=bar]

Chọn các phần tử không có thuộc tính foo với giá trị bằng bar

Attribute Value Begins: [@foo^=bar]

Chọn các phần tử có thuộc tính foo với giá trị bắt đầu bằng bar

Attribute Value Ends: [@foo$=bar]

Chọn các phần tử có thuộc tính foo với giá trị cuối bằng bar

Attribute Value Contains: [@foo*=bar]

Chọn các phần tử có thuộc tính foo với giá trị có chứa chuỗi bằng bar

Custom Selectors

Even Element (:even)

Chọn các phần tử chẵn, bạn cũng có thể sử dụng :nth-child(even) với chức năng tương tự

Odd Element (:odd)

Chọn các phần tử lẻ, bạn cũng có thể sử dụng :nth-child(odd) với chức năng tương tự

Nth Element (:eq(n), :nth(n))

Chọn phần tử theo thứ tự chỉ mục, phần tử đầu tiên bắt đầu với chỉ mục bằng 0, cách thức chọn này là khác với nth-child(n)

Greater Than :gt(n)

Chọn các phần tử có chỉ mục lớn hơn n, phần tử đầu tiên bắt đầu với chỉ mục bằng 0

Less Than : lt(n)

Chọn các phần tử có chỉ mục nhỏ hơn n, phần tử đầu tiên bắt đầu với chỉ mục bằng 0

First :first

Chọn phần tử đầu tiên, điều này là tương đương với nth(0), eq(0), còn nếu chọn theo phần tử con thì nó tương đương với nth-child(1)

Last :last

Chọn phần tử cuối cùng

Contains :contains(text)

Chọn các phần tử có chứa nội dung text

Visible :visible

Chọn các phần tử đang được hiển thị

Hidden :hidden

Chọn các phần tử đang được ẩn

Ở trên là những cách thức để bạn chọn phần tử trong jQuery, các bài viết thuộc seri jQuery basic chỉ mang hình thức giới thiệu dành cho những ai mới làm quen với jQuery, hoặc cũng là một bài ôn lại cho những ai đã hiểu về nó.

Tham khảo (jQuery Reference Guide and docs.jquery.com)

Biểu thức quy tắc trong javaScript (regular expression)

Cũng như những ngôn ngữ lập trình khác biểu thức quy tắc (regular expression/ RegExp) là một tính năng đắc lực để kiểm tra, so sánh, thay thế, tách, ghép một chuỗi nào đó theo một quy tắc bạn quy định, nếu bạn đã tìm hiểu về biểu thức quy tắc trong ngôn ngữ PHP rồi thì sẽ thấy javaScript cũng có cách quy định tương tự chỉ khác ở một số hàm xử lý biểu thức quy tắc. Có 2 phương thức của RegExp để kiểm tra là exec và test, có một vài phương thức của chuỗi hữu dụng với biểu thức quy tắc là search, match, split, replace.

Trong javaScript ta có 2 cách để khai báo biểu thức quy tắc:

  1. Khai báo với 2 dấu "/" ở đầu và cuối biểu thức
  2. Khai báo thông qua việc tạo đối tượng RegExp

Cách thứ nhất thường dùng nhiều hơn bởi sự đơn giản trong khai báo.

Khi xử lý một chuỗi với biểu thức điều kiện một điều quan trọng là bạn muốn khi áp dụng ký tự có phân biệt chữ in hoa in thường hay không và áp dụng cho đoạn chuỗi đầu tiên tìm được hay tất cả các đoạn chuỗi hợp quy tắc, ta sẽ được tìm hiểu điều này sau đây:

  •  "/quy tắc/" biểu thức có phân biệt chữ in hoa, in thường, và chỉ áp dụng cho đoạn chuỗi đầu tiên tìm thấy đúng quy tắc
  • "/quy tắc/g" biểu thức có phân biệt hoa - thường và áp dụng cho tất cả đoạn chuỗi hợp quy tắc
  • "/quy tắc/i" biểu thức không phân biệt hoa - thường, và chỉ áp dụng cho đoạn chuỗi đầu tiên tìm thấy đúng quy tắc
  •  "/quy tắc/gi" biểu thức không phân biệt hoa - thường, và áp dụng cho tất cả đoạn chuỗi hợp quy tắc

Ví dụ: thay ký tự n bằng dấu "*"

var str = 'Xin chào!, tôi là VANKHUONG 777';
var str1 = str.replace(/n/gi, '*');
document.write(str1);
// Xi* chào!, tôi là VA*KHUO*G 777
var str2 = str.replace(/n/,'*');
document.write(str2);
// Xi* chào!, tôi là VANKHUONG 777

Tiếp theo ta sẽ tìm hiểu cách viết biểu thức quy tắc với cách dùng ký tự đại diện được quy ước trong biểu thức.

Quy tắc về vị trí

  • "^" nghĩa là bắt đầu một chuỗi
  • "$" nghĩa là kết thúc một chuỗi
  • "\b" nghĩa là điểm giữa một ký tự là từ và ký tự không phải là từ, ký tự là từ ở đây là ký tự từ A-z, 0-9
  • "\B" ngược lại với '/b'

Ví du:

var str = 'ngo van khuong';
var str3 = str.replace(/n\b/, '*');
// str3: ngo va* khuong
var str4 = str.replace(/n\B/, '*');
// str4: *go van khuo*g

Quy tắc về những ký tự metasymbol

  • "." đại diện bất kỳ ký tự nào
  • "\d" đại diện cho một ký tự số từ 0-9, tương đương với cách viết [0-9]
  • "\D" đại diện cho một ký tự không phải là kiểu số từ 0-9, ngược lại với "\d"
  • "\s" đại diện cho một ký tự là khoảng trắng
  • "\S" đại diện cho một ký tự không phải là khoảng trắng, ngược lại với "\s"
  • "\w" đại diện cho một ký tự từ A-Z hoặc a-z hoặc 0-9, hoặc ký tự gạch dưới "_"
  • "\W" đại diện cho một ký tự không phải là từ A-Z, a-z, 0-9, ký tự gạch dưới "_"

Ví dụ:

var str = 'Xin chào!, tôi là VANKHUONG 777';
var str5 = str.replace(/\w/g, '*');
// str5: *** **à*!, *ô* *à ********* ***

Quy tắc về số lượng ký tự

  • "x?" nghĩa là một ký tự "x" hoặc không có ký tự nào
  • "x*" nghĩa là một hoặc nhiều ký tự "x" hoặc không có ký tự nào
  • "x+" nghĩa là có ít nhất một ký tự x
  • "x{n}" nghĩa là ký tự x lặp lại n lần
  • "x{n,}" nghĩa là ký tự x lặp lại ít nhất n lần
  • "x{n,m}" nghĩa là ký tự x lặp lại từ n tới m lần

Ví dụ:

var str = 'good night, godgad, gd, gooogle';
var str6 = str.replace(/go?d/gi, '*');
// str6: good night, *gad, *, gooogle
var str7 = str.replace(/g(oo)?d/gi, '*');
// str7: * night, godgad, *, gooogle
var str8 = str.replace(/go*d/gi, '*');
// str8: * night, *gad, *, gooogle
var str9 = str.replace(/go+/gi, '*');
// str9: *d night, *dgad, gd, *gle
var str10 = str.replace(/o{2}/gi, '*');
// str10: g*d night, godgad, gd, gooogle
var str11 = str.replace(/o{2,}/gi, '*');
// str11: g*d night, godgad, gd, g*gle
var str12 = str.replace(/go{1,3}d/gi, '*');
// str12: *d night, *dgad, gd, gooogle

Quy tắc về danh sách ký tự

  • "[...]" trong dấu ngoặc vuông liệt kê danh sách những ký tự hợp quy tắc, có thể dùng dấu gạch giữa "-"giữa 2 ký tự để thể hiện danh sách những ký tự trong khoảng 2 ký tự theo vị trí ASCII của ký tự
  • "[^...]" chức năng thì ngược lại với "[...]" thay vì liệt kê những ký tự hợp quy tắc, nó cho biết bất kỳ ký tự nào ngoài danh sách các ký tự trong dấu ngoặc vuông

Ví dụ:

var str ='ABCDEF, abcdef, 12345';
var str13 = str.replace(/[Ab1]/g, '*');
// str13: *BCDEF, a*cdef, *2345
var str14 = str.replace(/[A-Cd-f1-35]/g, '*');
// str14: ***DEF, abc***, ***4*
var str15 = str.replace(/[^A-f4-5]/g, '*');
// str15: ABCDEF**abcdef*****45

Với biểu thức quy tắc bạn có thể có nhiều cách viết khác nhau cùng theo một quy tắc hay cùng cho bạn kết quả giống nhau, có người viết dài người viết ngắn nhưng miễn sao bạn thấy giễ hiểu là được, nếu bạn viết quen thì biểu thức nhìn sẽ ngắn hơn. Nếu bạn không hiểu rõ các quy ước trong biểu thức quy tắc thì bạn cũng chẳng hiểu người khác viết gì vì đa số những người có kinh nghiệm đều viết biểu thức ngắn và chặt chẽ, hy vọng bạn thấy bài viết này bổ ích và có thể vận dụng nó một cách hiệu quả.

Đối số hàm trong javaScrip

Có thể nói javaScript là ngôn ngữ hướng đối tượng, hầu như mọi thứ trong javaScript đều làm việc theo hướng đối tượng như chuỗi, mảng...
bên trong mọi hàm javaSctipt đều tồn tại một biến theo ngữ cảnh có tên là arguments, nó không phải là một mảng đúng nghĩa vì mảng trong javaScript cũng là một đối tượng, với arguments bạn không thể thay đổi nó hay bạn không thể dùng phương thức push() để thêm những phần tử mới, nhưng bạn lại có thể truy cập những phần tử như cách trong mảng, nó cũng có thuộc tính length như trong mảng. Hãy xem xét những vị dụ sau để rõ hơn điều này.

Ví dụ bạn sẽ tạo ra một hàm với 2 đối số sau đó bạn sẽ gọi hàm trong 2 trường hợp: một là gọi hàm đó với 1 tham số, hai là gọi hàm đó với 2 tham số và tham số thứ 2 là một đối tượng, ở đây bạn sẽ sử dụngarguments để kiểm tra xem hàm có bao nhiêu đối số:

function sendMessage( msg, obj ) {
// Nếu có 2 đối số
if ( arguments.length == 2 )
  // gọi phương thức của đối tượng là đối số thứ 2
  obj.handleMsg( msg );
else
  alert( msg );
}
// Gọi hàm với một tham số
sendMessage( "Hello, World!" );

// Gọi hàm với tham số thứ 2 là một đối tượng có phương thức handleMsg
sendMessage( "How are you?", {
   handleMsg: function( msg ) {
     alert( "This is a custom message: " + msg );
  }
});

Ví dụ thứ 2 rõ ràng hơn, chúng ta sẽ truy cập arguments và gán các phần tử của nó vào một mảng đúng nghĩa:

function makeArray() {
  var arr = [];
  // Lặp các phần tử trong arguments và đưa vào mảng arr
  for ( var i = 0; i < arguments.length; i++ ) {
    arr.push( arguments[i] );
  }
  return arr;
}
var myarr = makeArray('one','two');

// Kiểm tra mảng trả về từ hàm makeArray
for(var i=0; i<myarr.length; i++){
  document.write(myarr[i] +'<br />');
}

 

Hiểu rõ về các phương thức sự kiện được viết trong jQuery

DOM cho chúng ta một số event để tương tác với người dùng trên DOM, nay chúng ta có nhiều lựa chọn hơn khi dùng jQuery, khá nhiều phương thức được viết trong jQuery để thực hiện cho một vài sự kiện người dùng trên DOM hoặc một số sự kiện tự định nghĩa, qua nhiều phiên bản tiến lên có một số phương thức trong jQuery đã được thay thế nhưng vẫn giữ lại hoặc đã bỏ đi, một vài liệt kê sau sẽ sơ lược lại những gì jQuery đã viết để có cách nhìn rõ ràng và tổng quát hơn về các phương thức sự kiện cũng như có mối liên hệ tới các sự kiện trong DOM.

bind()/on()/delegate()/one()

  • bind( eventType [, eventData ], handler )
  • on( events [, selector ] [, data ], handler )
  • delegate( selector, eventType, eventData, handler )
  • one( events [, selector ] [, data ], handler )

từ phiên bản 1.7 thì jQuery đưa vào on() lúc này bind(), delegate() và on() đều như nhau vì thực tế chỉ là bind() và delegate() gọi on(), nhưng on() có thể gắn một hành động cho một hoặc nhiều sự kiện tới những phần tử được chọn, bind() thì không có thêm tham số selector (trong jQuery bind() gọi on() với tham số selector là null). Các sự kiện được liệt kê trong chuỗi bằng khoảng trắng để cùng thực hiện một hành động hoặc có thể chuyển vào dạng object để viết hành động cho từng sự kiện. Trong code jQuery phương thức one() cũng gọi on() nhưng với tham số cuối bằng 1 điều này để one() thực hiện hành động cho sự kiện chỉ lần đầu tiên điều này cũng tương đương với việc ta gọi off() trong khi thực hiện một hành động cho sự kiện bằng gọi on(). Tóm lại mục đích chung của tất cả các phương thức trên thì cũng tương tự như addEventListener() của DOM (từ IE8 về trước thì là attachEvent)

unbind()/off()/undelegate()

unbind() và undelegate() đều gọi off(), mục đích thì cũng tương tự như removeEvenListener() của DOM (từ IE8 về trước thì là detachEvent)

live(), die()

đã được remove từ phiên bản 1.9

blur()/focusout(), focus()/focusin()

blur() được giới thiệu trước và sau đó jQuery đã giới thiệu thêm focusout() đây là 2 phương thức ngắn gọn của on(), hai phương thức này tương tự nhau vì thực tế là blur() gọi focusout(), mục đích giống như phương thức onblur() và onfocusout() của DOM. Sự khác nhau của 2 phương thức này ở chỗ focusout() sẽ có thể ảnh hưởng lên các phần tử con của nó còn blur() phải là chính nó. Trong jQuery thì focusout() có thể làm việc được trên cả firefox còn onfocusout() của DOM hiện tại thì không (ví dụ http://jsfiddle.net/tuG33/1/). Cách hiểu về focus() và focusin() cũng tương tự.

load(), unload(), resize(), scroll(), submit(), change(), select(), click(), dblclick(), keydown(), keyup(), keypress()

Một phương thức ngắn gọn của on(), mục đích giống như onload(), onunload(), onresize(), onscroll(), onsubmit(), onchange(), onselect(), onclick(), ondblclick(), onkeydown(), onkeyup(), onkeypress() của DOM. Cần phải nói thêm về sự khác nhau giữa keydown/keyup với keypress là keydown/keyup thực hiện gán hành động cho sự kiện với các phím(key) trên bàn phím lúc này chúng ta có keycode còn keypress cũng gán hành động cho sự kiện với các phím nhưng lúc này là charcode nghĩa là ký tự được nhập vào nên nó sẽ không làm việc với các phím không nhập ký tự như shift, alt hay ctrl..., ví dụ phím "a" có keycode là 65 còn charcode là 97

hover() / mouseenter(), mouseleave() / mouseover(), mouseout()

  • hover( handlerIn, handlerOut )

Một phương thức ngắn gọn của on(). Đây đều là những sự kiện về mouse khi rê con trỏ lên và rời khỏi một phần tử nhưng sự khác nhau là mouseover() và mouseout() ảnh hưởng lên cả phần tử con của nó còn 2 cái kia thì chỉ chính nó. Những sự kiện này cũng tương tự như các sự kiện onmouseenter(), onmouseleave(), onmouseover(), onmouseout() của DOM. Sự kiện hover() là phương thức gọn để thực hiện 2 sự kiện là mouseenter() và mouseleave(), các phương thức sự kiện khác như mousemove(), mouseup(), mousedown() thì mục đích cũng tương tự như các sự kiện của DOM

error()

Dùng để thực hiện một hành động nào đó khi hình ảnh hoặc một phần tử nào đó tải không đúng, hiện phương thức này đã được phản đối từ phiên bản 1.8, phương thức này cũng gần tương tự như onerror() của DOM