前言:最近公司后臺需要實(shí)現(xiàn)一個類似于選項(xiàng)卡的一個搜索眼坏,比如說點(diǎn)擊手機(jī)型號拂玻,下面出現(xiàn)很多選項(xiàng)如蘋果華為等,點(diǎn)擊其中一項(xiàng)宰译,再下面一行會出現(xiàn)你點(diǎn)擊的這個選項(xiàng)檐蚜,當(dāng)當(dāng)當(dāng),就像下圖這樣:
??點(diǎn)擊搜索按鈕沿侈,會收集選擇結(jié)果那一行需要的數(shù)據(jù)傳遞給后臺闯第。由于這種形式的搜索在其他頁面還會出現(xiàn)很多,所以缀拭,需要我把他們進(jìn)行一下封裝咳短,前提是從后臺接收到的數(shù)據(jù)結(jié)構(gòu)都是一樣的。
關(guān)鍵詞:$.fn $.extend prototype 選項(xiàng)卡 封裝 ......
正文:
1蛛淋、需求:
運(yùn)營提了要求诲泌,像很多插件一樣,當(dāng)他們想要用的時候铣鹏,只需要在html里面寫一個帶有class的div敷扫,在script里面寫入function然后傳入數(shù)據(jù)就行:
html:
......
<div class="box"> </div>
......
script:
......
$('.box').tagRel({
data:${dataValue}
});
......
js:
(function($,window){
function tagRel(element,options){
this.element = $(element);
this.options = $.extend({}, options);
this._createDom();
this._tabInit();
this._tabToggle();
this._labelClick();
this._chosenClose();
}
tagRel.prototype = {
//0:createDom
_createDom : function(){
var data = this.options.data,//要循環(huán)的數(shù)組
divHiddenForm = '',//隱藏域,放在this.element的前面
diva= '',
divb= '',
divc= '',
divaLi = '',//diva的tabli
divbPane = '';//divb的tab-pane
//divbPaneLi = '';//divb的tab-pane-li
divHiddenForm = '<form id="searchForm" method="post" style="display:none">' +
'<table class="search-table">' +
'<tr>' +
'<th>標(biāo)簽名稱:</th>' +
'<td><input id="hidden" name="condition" type="text"/></td>' +
'</tr>' +
'</table>' +
'</form>';
//循環(huán)divaLi,divbPane
$.each(data,function(i,item){
......(省略)
})
diva = '<div class="title-box clearfix">'+
'<span class="labelValue">標(biāo)簽:</span>'+
'<ul class="tab-nav">'+divaLi+'</ul>'+
'</div>';
divb = '<div class="tab-content">'+divbPane+'</div>';
divc = '<div class="tab-footer clearfix">'+
'<span class="labelValue">選擇結(jié)果:</span>'+
'<ul class="chosen-box"></ul>'+
'</div>';
//1:this.element之前放入隱藏域
this.element.before(divHiddenForm);
//2:this.element里面放入tab-title-box
this.element.append(diva);
//3:this.element里面放入tab-content-box
this.element.append(divb);
//4:this.element里面放入tab-chosen-box
this.element.append(divc);
},
//1:tab初始化
_tabInit : function(){
$('.tab-li').eq(0).addClass('active');//第一個標(biāo)簽?zāi)J(rèn)選中#
$('.tab-pane').eq(0).stop().fadeIn();//第一個div默認(rèn)顯示
},
//2:tab切換
_tabToggle : function(){
var self = this;
$('.tab-li').click(function(e){
var liIndex = $(this).index();
$(this).addClass('active');
$(this).siblings().removeClass('active');
$('.tab-pane').hide();
$('.tab-pane').eq(liIndex).stop().fadeIn();
})
},
//3:label點(diǎn)擊
_labelClick : function(e){
...(省略诚卸,這里就是一個點(diǎn)擊標(biāo)簽葵第,下層結(jié)果出現(xiàn)標(biāo)簽的效果)
},
//4:chosenClose關(guān)閉
_chosenClose : function(e){
var self= this;
$(".layui-tab-close").live('click',function(e){
e.stopPropagation();
var dataId = $(this).closest('li').attr('data-id');
var targetli = $('.tab-content').find('li[data-id='+dataId+']');
targetli.removeClass('active');
$(this).closest('li').remove();
self._collection();
})
},
//5:collect:收集結(jié)果
_collection:function(){
//收集信息
var arr = [];
$('.chosen-box li').each(function(){
var key = $(this).attr('data-tag'),
keyValue =$(this).attr('data-val'),
json = {};
json.tagName = key;
json.tagValue = keyValue;
arr.push(json);
})//console.log(arr);//最終傳輸數(shù)據(jù)。
$('#hidden').val(JSON.stringify(arr));
}
}
$.fn.tagRel = function(options){
new tagRel(this,options);
}
})(jQuery,window);
好合溺,上面是代碼卒密,下面就是幾行重要代碼的解析:
先看下面這張圖片,比較直觀:
這張圖片是上述代碼收縮了部分棠赛,比較能夠突出我要說的重點(diǎn):
重點(diǎn)一:
我們用寫插件的人的思維來思考哮奇,我們肯定是需要一個函數(shù)的膛腐,這個函數(shù)要接受到script里面?zhèn)鬟^來的參數(shù)。所以鼎俘,我們先寫一個函數(shù)哲身。就是上圖中的函數(shù)一。
函數(shù)一接收了兩個參數(shù)贸伐。一個是element,一個是options勘天。element就代表著script里面是是哪個標(biāo)簽觸發(fā)了這個函數(shù),就是那個$(),里面是class捉邢。而options就是接收到的數(shù)據(jù)脯丝。
重點(diǎn)二:
$.extend({},options):
$.extend()有兩種用法
??一種是擴(kuò)展方法。
??另一種是合并對象獲得一個新的對象伏伐。
這里宠进,我們介紹一下合并對象這個方法:
一般的插件中,比如說拖拽插件藐翎,表格插件材蹬,都會有一些默認(rèn)的參數(shù),那是在具體實(shí)例化時數(shù)據(jù)參數(shù)未傳進(jìn)來的時候阱高,這些默認(rèn)的參數(shù)不會讓展示出來的頁面看起來垮掉赚导,哈哈茬缩。
下面是找到的兩個插件的默認(rèn)參數(shù)default:
拖拽插件:
表格插件:
大家是否覺得有點(diǎn)不一樣赤惊,其實(shí),細(xì)心的人發(fā)現(xiàn)凰锡,本質(zhì)上兩個是一樣的未舟,只不過表格插件是合起來寫了。
例如:
var settings={validate:false,limit:5,name:"sm"};
var defaults={validate:true,limit:2}
var settings=$.extend(defaults,settings);
結(jié)果:settings={validate:false,limit:5,name:"sm"}
重點(diǎn)三:
現(xiàn)在有了函數(shù)了掂为,那么我們對于這個tab的一些操作都寫在哪里呢,寫在原型里吧裕膀,可隨時取用。
重點(diǎn)四:
封裝起來就可以了嗎勇哗?不行的昼扛,因?yàn)槲覀兠看蝹鲄?shù)使用的時候是一個實(shí)例:
所以,最后那個函數(shù)的意思如下:
$.fn是指jquery的命名空間欲诺,加上fn上的方法及屬性抄谐,會對jquery實(shí)例每一個有效。如擴(kuò)展$.fn.abc()扰法。
在 jQuery 中蛹含,fn 其實(shí)就是 JavaScript 中 propotype 的一個別名,$ 是 jQuery 的別名塞颁,所以
$.fn.tagRel等同于 jQuery.prototype.pluginName浦箱。舉個簡單的小例子:
('li') 是一個對象吸耿,它的 key 有 length,它的原型(共享屬性)為 jQuery.prototype酷窥,jQuery.prototype 的 key 有 addClass咽安、removeClass、text竖幔、html 和 on 等板乙。 \.fn.tagRel表示創(chuàng)建一個 jQuery 的屬性,通俗的說是寫一個 jQuery 函數(shù),tagRel才是函數(shù)名
eg:
$.fn.setRedText = function() {
return $(this).css("color", "red");
};
$("p").setRedText();