# jQuery 規范
## 使用最新版本的 jQuery
最新版本的 jQuery 會改進性能和增加新功能,若不是為了兼容舊瀏覽器,建議使用最新版本的 jQuery。以下是三條常見的 jQuery 語句,版本越新,性能越好:
~~~
$('.elem')
$('.elem', context)
context.find('.elem')
~~~
*分別使用 1.4.2、1.4.4、1.6.2 三個版本測試瀏覽器在一秒內能夠執行多少次,結果 1.6.2 版執行次數遠超兩個老版本。*
## jQuery 變量
1. 存放 jQuery 對象的變量以?`$`?開頭;
2. 將 jQuery 選擇器返回的對象緩存到本地變量中復用;
3. 使用駝峰命名變量;
~~~
var $myDiv = $("#myDiv");
$myDiv.click(function(){...});
~~~
## 選擇器
1. 盡可能的使用 ID 選擇器,因為它會調用瀏覽器原生方法?`document.getElementById`?查找元素。當然直接使用原生?`document.getElementById`?方法性能會更好;
2. 在父元素中選擇子元素使用?`.find()`?方法性能會更好, 因為 ID 選擇器沒有使用到 Sizzle 選擇器引擎來查找元素;
~~~
// Not recommended
var $productIds = $("#products .class");
// Recommended
var $productIds = $("#products").find(".class");
~~~
## DOM 操作
1. 當要操作 DOM 元素的時候,盡量將其分離節點,操作結束后,再插入節點;
2. 使用字符串連接或?`array.join`?要比?`.append()`性能更好;
~~~
var $myList = $("#list-container > ul").detach();
//...a lot of complicated things on $myList
$myList.appendTo("#list-container");
~~~
~~~
// Not recommended
var $myList = $("#list");
for(var i = 0; i < 10000; i++){
$myList.append("<li>"+i+"</li>");
}
// Recommended
var $myList = $("#list");
var list = "";
for(var i = 0; i < 10000; i++){
list += "<li>"+i+"</li>";
}
$myList.html(list);
// Much to recommended
var array = [];
for(var i = 0; i < 10000; i++){
array[i] = "<li>"+i+"</li>";
}
$myList.html(array.join(''));
~~~
## 事件
1. 如果需要,對事件使用自定義的?`namespace`,這樣容易解綁特定的事件,而不會影響到此 DOM 元素的其他事件監聽;
2. 對 Ajax 加載的 DOM 元素綁定事件時盡量使用事件委托。事件委托允許在父元素綁定事件,子代元素可以響應事件,也包括 Ajax 加載后添加的子代元素;
~~~
$("#myLink").on("click.mySpecialClick", myEventHandler);
$("#myLink").unbind("click.mySpecialClick");
~~~
~~~
// Not recommended
$("#list a").on("click", myClickHandler);
// Recommended
$("#list").on("click", "a", myClickHandler);
~~~
## 鏈式寫法
1. 盡量使用鏈式寫法而不是用變量緩存或者多次調用選擇器方法;
2. 當鏈式寫法超過三次或者因為事件綁定變得復雜后,使用換行和縮進保持代碼可讀性;
~~~
$("#myDiv").addClass("error").show();
~~~
~~~
$("#myLink")
.addClass("bold")
.on("click", myClickHandler)
.on("mouseover", myMouseOverHandler)
.show();
~~~
## 其他
1. 多個參數使用對象字面量存儲;
2. 不要將 CSS 寫在 jQuery 里面;
3. 正則表達式僅準用 .test() 和 .exec() 。不準用 "string".match() ;
## jQuery 插件模板
~~~
// jQuery Plugin Boilerplate
// A boilerplate for jumpstarting jQuery plugins development
// version 1.1, May 14th, 2011
// by Stefan Gabos
// remember to change every instance of "pluginName" to the name of your plugin!
(function($) {
// here we go!
$.pluginName = function(element, options) {
// plugin's default options
// this is private property and is accessible only from inside the plugin
var defaults = {
foo: 'bar',
// if your plugin is event-driven, you may provide callback capabilities
// for its events. execute these functions before or after events of your
// plugin, so that users may customize those particular events without
// changing the plugin's code
onFoo: function() {}
}
// to avoid confusions, use "plugin" to reference the
// current instance of the object
var plugin = this;
// this will hold the merged default, and user-provided options
// plugin's properties will be available through this object like:
// plugin.settings.propertyName from inside the plugin or
// element.data('pluginName').settings.propertyName from outside the plugin,
// where "element" is the element the plugin is attached to;
plugin.settings = {}
var $element = $(element), // reference to the jQuery version of DOM element
element = element; // reference to the actual DOM element
// the "constructor" method that gets called when the object is created
plugin.init = function() {
// the plugin's final properties are the merged default and
// user-provided options (if any)
plugin.settings = $.extend({}, defaults, options);
// code goes here
}
// public methods
// these methods can be called like:
// plugin.methodName(arg1, arg2, ... argn) from inside the plugin or
// element.data('pluginName').publicMethod(arg1, arg2, ... argn) from outside
// the plugin, where "element" is the element the plugin is attached to;
// a public method. for demonstration purposes only - remove it!
plugin.foo_public_method = function() {
// code goes here
}
// private methods
// these methods can be called only from inside the plugin like:
// methodName(arg1, arg2, ... argn)
// a private method. for demonstration purposes only - remove it!
var foo_private_method = function() {
// code goes here
}
// fire up the plugin!
// call the "constructor" method
plugin.init();
}
// add the plugin to the jQuery.fn object
$.fn.pluginName = function(options) {
// iterate through the DOM elements we are attaching the plugin to
return this.each(function() {
// if plugin has not already been attached to the element
if (undefined == $(this).data('pluginName')) {
// create a new instance of the plugin
// pass the DOM element and the user-provided options as arguments
var plugin = new $.pluginName(this, options);
// in the jQuery version of the element
// store a reference to the plugin object
// you can later access the plugin and its methods and properties like
// element.data('pluginName').publicMethod(arg1, arg2, ... argn) or
// element.data('pluginName').settings.propertyName
$(this).data('pluginName', plugin);
}
});
}
})(jQuery);
~~~
此 jQuery 插件模板出自:[jQuery Plugin Boilerplate, revisited](http://stefangabos.ro/jquery/jquery-plugin-boilerplate-revisited/)