Blogs
Tự tạo plugin jQuery, tại sao không?
Thành tố tương tác (như thanh trượt, galleries hoặc đơn tương tác) là những đối tượng làm việc rất quen thuộc với một lập trình viên. Bạn hoàn toàn có thể tạo thủ công các thành tố này cho từng site một. Nhưng hãy tưởng tượng, bạn sẽ tiếp kiệm được bao nhiêu thời gian khi có thể gói khâu này thành plugin jQuery tiện dụng?
Trong bài viết, chúng ta sẽ tìm hiểu cách tự xây dựng jQuery plugin của riêng mình. Bạn sẽ biết được những điều kiện cần có để cho ra đời một plugin chất lượng và hiệu quả một cách nhanh chóng.
Kế tiếp, để thể hiện các phần khác nhau của một plugin, ta sẽ dùng fancytoggle. Đây là một plugin mẫu đơn giản, dùng để toggle hiển thị nested element (như list items), và để tạo accordion-style widgets cho các phần như FAQs. Nhìn chung, ý tưởng dựa trên khái niệm cơ bản nhất cần có ở plugins, ví dụ sau sẽ cho bạn thấy sự liên kết này trong thực tế.
See the Pen FancyToggle by SitePoint (@SitePoint) on CodePen.
Lợi ích từ việc sử dụng plugin
Ở đây, mục đích chính là tạo ra một công cụ mở rộng tiện dụng, mà chúng ta có thể thêm vào project được. Và chức năng plugin của jQuery sẽ phần nào giúp ta đơn giản hóa nhiều công việc.
Một thế mạnh của những plugin này là: lập trình viên có thể xác định sử dụng tùy chọn nào để tùy chỉnh chức năng. Bạn hoàn toàn có thể thêm vào một số tùy chọn có khả năng thay đổi hoàn toàn cách làm việc của một plugin, hoặc cũng có thể dùng vừa đủ tùy chọn chỉ để người dùng lựa chọn styling và layout mong muốn. Với plugins, bạn có thể làm mọi thứ theo ý mình.
Phát triển jQuery Plugins
Hãy xem thử các bước cần làm để đăng ký plugin jQuery mới. Chúng ta sẽ tiếp tục sử dụng plugin fancyToggle làm ví dụ.
Creating our function with $.fn
jQuery plugins hoạt động bằng cách đăng ký một function với tên bạn muốn call để kích hoạt plugin (ví dụ, bạn sẽ call các inbuilt function .width()
hay .height()
để trả kết quả độ rộng/chiều cai)
Chúng ta sẽ gán function vào object $.fn
trong jQerry để có thể sử dụng function trên object $
global. Như vậy, function của ta đã được đăng ký và có thể call được lên objects hoặc selections.
1
2
3
4
5
6
|
//Đăng ký function
$ . fn . fancytoggle = function ( ) {
// ...
} ;
|
Chỉ đơn giản thế thôi! Đến đây chúng ta có thêm method mới call được tùy thích từ object $
của jQuery. Ví dụ như:
1
2
3
4
|
//Call fancytoggle lên thành tố này
$ ( '.my-element' ) . fancytoggle ( ) ;
|
Với $.fn
, bạn muốn đăng ký bao nhiêu functions cũng được. Tuy nhiên, bạn nên tránh đăng ký hơn một function, trừ khi plugin còn dùng cho một công việc hoàn toàn khác nữa.
Multiple collections and looping
Nên nhớ, khi bạn call plugin của mình, plugin có thể tự áp dụng lên một hoặc nhiều thành tố. Ví dụ, nếu chúng ta áp dụng fancytoggle()
đến nhiều items khác nhau, function của chúng ta sẽ phải xử lý cả collection.
Để xử lý mỗi thành tố, chúng ta chỉ cần lặp cả collection với function $.each
trong jQerry:
1
2
3
4
5
6
7
8
9
10
|
$ . fn . fancytoggle = function ( options ) {
// `this` ám chỉ thành tố jQuery call plugin
this . each ( function ( index , value ) {
// phần chức năng còn lại của plugin
} ) ;
return this ;
} ;
|
Cứ lặp lại như vậy với mỗi thành tố trong collection. với $.each
, dù có phải thực hiện tính toán, thêm event listener,… đi nữa, thì cũng vẫn đảm bảo được chúng ta sẽ tham chiếu đến đúng thành tố.
Trả objects / chaining
Trong đa số trường hợp, khi bạn trực tiếp call plugin lên một object hay selector, tính năng của plugin sẽ chạy lên item đó.
Trong jQerry, ta còn có khái niệm chaining
, với chaining
bạn có thể liên tục call hàng loạt methods lên một item duy nhất và mỗi method sẽ thực thi theo thứ tự:
1
2
3
4
5
6
|
// Chaining một vài jQuery methods lên một selector
$ ( '.my-element' )
. addClass ( 'active' )
. slideToggle ( 'fast' ) ;
|
Quá trình chaining
sẽ chỉ thị một thành tố, thêm active class và đẩy thành tố lên hoặc xuống. Mỗi method sẽ trả kết quả một object, obejct này tiếp tục được call bởi method tiếp theo.
Để plugin làm việc được theo cách này, chúng ta chỉ cần trả item tại cuối function của plugin. Bước này được khuyến khích cao, tuy về mặt kỹ thuật, bạn không nhất thiết phải làm vậy.
1
2
3
4
5
6
7
|
// xác định và trả kết quả function của plugin
$ . fn . fancytoggle = function ( ) {
// ...
return this ;
} ;
|
Tạo options và configurations
Thông qua một loạt tùy chọn, cách làm việc của plugin có thể được thay đổi. Những tùy chọn này, dưới dạng cặp key/value (một kiểu object trong JavaScript), sẽ thay đổi được cả function của bạn:
1
2
3
4
5
6
7
|
// áp dụng fancyToggle lên thành tố này (và tùy chỉnh giá trị ta có)
$ ( '.my-element' ) . fancytoggle ( {
openSpeed : 300 ,
closeSpeed : 600 ,
} ) ;
|
Để plugin của chúng ta có được khả năng xử lý tùy chọn, ta cần phải xác định cần sử dụng thiết lập mặc định như thế nào. Sau đó, chúng ta có thể dùng method $.extend
để kết hợp tùy chọn mặc định của ta với các tùy chọn đã đệ trình khi plugin được call:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
$ . fn . fancytoggle = function ( options ) {
// default arguments
options = $ . extend ( {
openSpeed : 400 ,
closeSpeed : 400 ,
easing : 'linear' ,
// tất cả tùy chọn đều ở đây
} , options ) ;
// ...
return this ;
}
|
Bạn có thể thoải mái tạo vô số tùy chọn cho plugin của mình $.extend
sẽ tạo một object duy nhất bằng cách kết hợp và thu thập giá trị. Bạn nên thêm một vài thiết lập cơ bản hoặc các thành tố giúp plugin “tự cài đặt”.
Với plugin chúng ta đang xây dựng, ta cần một số tùy chọn để xác định được plugin sẽ làm việc ra sao. Ví dụ, ta muốn người dùng có thể toggle mở khu vực như ý muốn. Tuy nhiên, chúng ta cũng có thể tùy chỉnh cho phép chúng chỉ được toggle từng section một (và đóng các sections khác). Trong lúc thực hiện toggle function, chúng ta sẽ kiểm tra xem liệu ta nên đóng các items khác hay không, dựa theo thiết lập này.
1
2
3
4
5
6
7
8
9
10
11
|
options = $ . extend ( {
singleItemOpen : false ,
} , options ) ;
// Trong toggle function của ta sau đó
if ( options . singleItemOpen === true ) {
var $ activePanel = $ item . siblings ( '.active' ) ;
animate ( $ activePanel , 'data-min-height' , 'data-close-speed' ) ;
}
|
Event listeners
Event listeners là các functions được call ở những sự kiện cụ thể trong vòng đời plugin. Những callback này sẽ giúp người khác hiểu ngay được các phần then chốt trong plugin của bạn và có thể kích hoạt chức năng chức năng của plugin.
Nhiều plugin jQuery cũng có các callbacks tương tự như thế này; ví dụ khi click qua slide-show hoặc đóng modal window.
Bạn sẽ xác định những callback này làm thành tố cho tùy chọn mặc định. Bắt đầu bằng việc thêm những tên sự kiện này hoặc thiết lập giá trị của chúng sang empty functions:
1
2
3
4
5
6
7
8
|
options = $ . extend ( {
// ...,
onItemClick : function ( ) { } ,
onItemOpen : function ( ) { } ,
onItemClose : function ( ) { }
} , options ) ;
|
Thay vì sử dụng hết tất cả empty functions trên, jQuery còn cung cấp function $.noop
. Function này có vai tròng tương tự, nhựng bạn nên chú ý tài nguyên khi tạo nhiều anonymous functions.
1
2
3
4
5
6
7
|
options = $ . extend ( {
onItemClick : $ . noop ,
onItemOpen : $ . noop ,
onItemClose : $ . noop
} , options ) ;
|
Khi đã tối ưu thiết đặt, bạn có thể bắt đầu xây dựng chức năng tại thời điểm callbacks xảy ra.
Callbacks làm việc bằng cách call tùy chọn của bạn khi kích hoạt. Ví dụ, trong plugin của ta, chúng ta có callback onItemClick
cần luôn được kích hoạt mỗi khi có người click lên toggle item. Kế tiếp, chúng ta sẽ sử dụng method call
để kích hoạt event listener (nếu đã có set trước).
Hãy xem thử:
1
2
3
4
5
6
7
8
9
|
// được call khi ta click lên toggle items
function toggle ( $ item , event ) {
// kích hoạt event listener
options . onItemClick . call ( null , $ item , event ) ;
} ) ;
|
Như vậy, khi chúng ta toggle items, ta sé chuyển đi ba tham số. Tham số đầu tiên là null
: chúng ta làm như vậy để sau này, khi chúng ta mở rộng callback sẽ không cần phải lo về giá trị của this
.
Tham số thứ hai là $item
(thành tố được toggled): đây là tham số khá quan trọng vì tham số này trao quyền truy cập của chính item cho callback function.
Cuối cùng, ta có tham số event
(cũng chính là sự kiện ta đang đã nói đến).
Event listener sẽ có quyền truy cập đến cả $item
và event
; đồng thời có thể tủy chỉnh chức năng của chúng ta. Ví dụ, nếu ta muốn loại bỏ thành tố khi được click:
1
2
3
4
5
6
7
8
9
|
$ ( '.my-element' ) . fancytoggle ( {
// khi click, xóa bỏ item và log
onItemClick : function ( $ item , event ) {
$ item . remove ( ) ;
console . log ( 'Removed this item!' ) ;
}
} ) ;
|
Đây là một trong nhiều lý do khiến sự kiện linh hoạt như vậy. Sự kiện có thể giúp developer truy cập plugin tại những thời điểm thêm chốt, để từ đó có thể mở rộng hoặc thay đổi cho phù hợp với nhu cầu riêng.
progressive enhancement
Như vậy, câu hỏi cần đặt ra là: nếu JS bị vô hiệu hóa thì sao? Không có JS, plugin của chúng ta sẽ không cách nào hoạt động được.
Ví dụ như, khi ta tạo toggleable sections với title và content body (click vào title để toggle body chạy lên và xuống). Nếu chúng ta không mở JS, cotent vẫn hoạt động như thường.
Hãy để ý những trường hợp như trên đễ tránh những sự cố không mong muốn.
Bạn muốn nhiều hơn nữa?
Mở rộng kiến thức
Với những kiến thức cơ bản được giới thiệu trong bài, tôi tin rằng các bạn hẳn đã phần nào có thể cho ra đời những plugin đơn giản nhưng cũng không kém phần hiệu quả cho các project tiếp theo của mình. Để cải thiện plugin hơn nữa, các bạn có thể tìm hiểu thêm nhiều bài viết khác về phát triển plugin. Trong đó, chính trang web của jQuery cũng có nhiều đoạn khá hay về khía cạnh này.
Đào sâu vào plugin
Cách học tập tốt nhất là thực hành. Chỉ khi bắt tay vào công việc, bạn mới nhận ra những thiếu sót và thế mạnh của bản thân.
Bạn cũng có thể xem thử và thử nghiệm với fancytoggle ví dụ trong bài viết, bạn có thể tìm hiểu thêm về plugin mẫu này trên CodePen. Bạn có thể:
- Thêm tùy chọn mới vào default arguments (và có thể override luôn)
- Thêm sự kiện vào plugin (như khi toggle area resize hoặc sau khi plugin khởi động)
- Dùng các sự kiện sẵn có để mở rộng chức năng của plugin (ví dụ như kích hoạt fade-in animation khi một section mở ra và mờ đi khi đóng lại)
Tóm tắt: bài viết có những gì
- Thêm plugin vào namespace của jQuery với
$.fn
- Xử lý nhiều collections bằng vòng lặp
.each
- Cách tạo method chain được
- Cách tạo tùy chọn mặc định và kết hợp tùy chọn với custom values đã chuyển giao
- Cách tận dụng callback để trao quyền truy cập vào tính năng của plugin cho developer
- Tìm hiểu sơ bộ về progressive enhancement (trường hợp khi không thể dùng được JS)
(sitepoint)
Có thể bạn quan tâm:
Hướng dẫn cài ứng dụng, phần mềm cho Android trực tiếp bằng tập ...
Danh sách chợ ứng dụng ngoài Google Play và AppStore
Ứng dụng quản lý vận tải trên smartphone
Ứng dụng đọc kinh, sách Phật Giáo trên smartphone và máy tính bảng
Cài đặt ứng dụng, game có đuôi .jar(.jad) cho Blackberry
Cách đưa ứng dụng của bạn lên top trên chợ ứng dụng di động
Giá gia công phần mềm, giá viết ứng dụng, giá thiết kế website
Tạo ứng dụng Android và iOS miễn phí cho website
Ứng dụng bán hàng trên smartphone, smart TV, mạng xã hội...
DVMS chuyên:
- Tư vấn, xây dựng, chuyển giao công nghệ Blockchain, mạng xã hội,...
- Tư vấn ứng dụng cho smartphone và máy tính bảng, tư vấn ứng dụng vận tải thông minh, thực tế ảo, game mobile,...
- Tư vấn các hệ thống theo mô hình kinh tế chia sẻ như Uber, Grab, ứng dụng giúp việc,...
- Xây dựng các giải pháp quản lý vận tải, quản lý xe công vụ, quản lý xe doanh nghiệp, phần mềm và ứng dụng logistics, kho vận, vé xe điện tử,...
- Tư vấn và xây dựng mạng xã hội, tư vấn giải pháp CNTT cho doanh nghiệp, startup,...
Vì sao chọn DVMS?
- DVMS nắm vững nhiều công nghệ phần mềm, mạng và viễn thông. Như Payment gateway, SMS gateway, GIS, VOIP, iOS, Android, Blackberry, Windows Phone, cloud computing,…
- DVMS có kinh nghiệm triển khai các hệ thống trên các nền tảng điện toán đám mây nổi tiếng như Google, Amazon, Microsoft,…
- DVMS có kinh nghiệm thực tế tư vấn, xây dựng, triển khai, chuyển giao, gia công các giải pháp phần mềm cho khách hàng Việt Nam, USA, Singapore, Germany, France, các tập đoàn của nước ngoài tại Việt Nam,…
Quý khách xem Hồ sơ năng lực của DVMS tại đây >>
Quý khách gửi yêu cầu tư vấn và báo giá tại đây >>