## 1.5\. jQuery插件配置項
這其實算一個高級話題:
* 會用jquery是第一階段
* 能抽象成插件是第二階段
* 讓插件足夠靈活強大是第三階段
代碼位于plugin_second
配置項分2類
* 普通配置項
* 回調函數
### 1.5.1\. 迭代1:普通配置項
回顧一下之前tab,發現我們的tab是只能鼠標移動到上面才能切換,那是不是所有tab都這樣呢? 當然不是了,我們看到很多網站的tab都是點擊切換的,那么我們如何能讓我們的tab支持這2種方式呢?
### 1.5.2\. 支持tab觸發事件選項
```
;(function($) {
$.fn.tab = function(options) {
// 將defaults 和 options 參數合并到{}
var opts = $.extend({},$.fn.tab.defaults,options);
return this.each(function() {
var obj = $(this);
$(obj).find('.tab_header li').on(opts.trigger_event_type, function (){
$(obj).find('.tab_header li').removeClass('active');
$(this).addClass('active');
$(obj).find('.tab_content div').hide();
$(obj).find('.tab_content div').eq($(this).index()).show();
})
});
// each end
}
//定義默認
$.fn.tab.defaults = {
trigger_event_type:'click', //mouseover | click 默認是click
};
})(jQuery);
```
這就是普通配置項的例子,配置項的值是js支持的類型
### 1.5.3\. 示例1
首先看一下plugin_second/jQuery.tab.html它沒有任何變化
```
<script>
$(function(){
$('.tab').tab();
});
</script>
```
默認項是click,所以這個tab只能點擊
### 1.5.4\. 示例2
看一下plugin_second/jQuery.tab_more.html,第一個tab只能點擊,第二個tab只能鼠標劃過
```
<script>
$(function(){
$('.tab_click').tab({
trigger_event_type:'click', //mouseover | click 默認是click
});
$('.tab_mouseover').tab({
trigger_event_type:'mouseover', //mouseover | click 默認是click
});
});
</script>
```
這里補充一點:第一個tab完全和例子一樣,既然默認項都是click,再寫的話就真有點 **_脫褲子放屁-多此一舉_** 了
[plugin_2](examples/jquery_plugin/plugin_second/jQuery.tab.html)
### 1.5.5\. 迭代2:回調函數
jquery_plugin/plugin_three
既然用tab,就是利用它可以在一個地方顯示多個內容,點擊的時候切換對應的tab content,tab內容不可能都是靜態的,那么這時候怎么辦?
是不是應該在點擊的時候更改內容呢?答案是回調函數,笨啦,前面不是說配置項有2種么?
### 1.5.6\. 回調函數
這就是普通配置項的例子,配置項的值是js支持的類型
```
;(function($) {
$.fn.tab = function(options) {
// 將defaults 和 options 參數合并到{}
var opts = $.extend({},$.fn.tab.defaults,options);
return this.each(function() {
var obj = $(this);
$(obj).find('.tab_header li').on(opts.trigger_event_type, function (){
$(obj).find('.tab_header li').removeClass('active');
$(this).addClass('active');
$(obj).find('.tab_content div').hide();
$(obj).find('.tab_content div').eq($(this).index()).show();
opts.change($(this).index());
})
});
// each end
}
//定義默認
$.fn.tab.defaults = {
trigger_event_type:'click', //mouseover | click 默認是click
change: function(index){
console.log('current index = ' + index);
}
};
})(jQuery);
```
### 1.5.7\. 生效了么?
打開jquery_plugin/plugin_three/jQuery.tab.html

### 1.5.8\. 變動
1. 增加了change配置項
```
//定義默認
$.fn.tab.defaults = {
......
change: function(index){
console.log('current index = ' + index);
}
};
```
2. 在插件內部調用了此回調函數
```
return this.each(function() {
var obj = $(this);
$(obj).find('.tab_header li').on(opts.trigger_event_type, function (){
......
opts.change($(this).index());
})
});
```
### 1.5.9\. 回調函數最需要注意的問題
* 調用場合,在什么地方調用,這是生命周期的核心問題
* 參數,確保在調用處有這些值
* 回調函數也要有默認行為的
[plugin_3](examples/jquery_plugin/plugin_three/jQuery.tab.html)
### 1.5.10\. 總結
| 配置項類型 | 數據類型 | 特點 |
| --- | --- | --- |
| 普通配置項 | js基本類型 | 不可變 |
| 回調函數配置項 | 函數 | 可變行為 |
### 1.5.11\. 迭代3:重構代碼
jquery_plugin/plugin_four
[plugin_4](examples/jquery_plugin/plugin_four/jQuery.tab.html)
```
;(function($) {
/**
* 公共函數: 初始化tab出發事件
*/
function init_tab_trigger_event(container,opts) {
$(container).find('.tab_header li').on(opts.trigger_event_type, function (){
$(container).find('.tab_header li').removeClass('active');
$(this).addClass('active');
$(container).find('.tab_content div').hide();
$(container).find('.tab_content div').eq($(this).index()).show();
opts.change($(this).index());
})
}
/**
* 公共函數: 初始化tab出發事件
*/
function init_with_config(opts){
_init_aaa_with_config(opts);
_init_bbb_with_config(opts);
_init_ccc_with_config(opts);
}
/**
* 私有函數
*/
function _init_aaa_with_config(opts){
}
function _init_bbb_with_config(opts){
}
function _init_ccc_with_config(opts){
}
$.fn.tab = function(options) {
// 將defaults 和 options 參數合并到{}
var opts = $.extend({},$.fn.tab.defaults,options);
return this.each(function() {
var obj = $(this);
// 根據配置進行初始化
init_with_config(opts);
// 初始化tab出發事件
init_tab_trigger_event(obj,opts);
});
// each end
}
//定義默認
$.fn.tab.defaults = {
trigger_event_type:'click', //mouseover | click 默認是click
change: function(index){
console.log('current index = ' + index);
}
};
})(jQuery);
```
### 1.5.12\. 將插件核心邏輯,抽象成公共函數
```
return this.each(function() {
var obj = $(this);
// 根據配置進行初始化
init_with_config(opts);
// 初始化tab出發事件
init_tab_trigger_event(obj,opts);
});
```
### 1.5.13\. 將大的公共函數拆解成n個私有函數
```
/**
* 公共函數: 初始化tab出發事件
*/
function init_with_config(opts) {
// 調用私有函數
_init_aaa_with_config(opts);
// 調用私有函數
_init_bbb_with_config(opts);
// 調用私有函數
_init_ccc_with_config(opts);
}
/**
* 私有函數
*/
function _init_aaa_with_config(opts) {
}
function _init_bbb_with_config(opts) {
}
function _init_ccc_with_config(opts) {
}
```
### 1.5.14\. 注意注釋和編碼規范
函數注釋
```
/**
* 私有函數
*/
function _init_aaa_with_config(opts) {
}
```
函數內注釋
```
// 調用私有函數
_init_ccc_with_config(opts);
```
函數體前面加一個空格