jQuery插件實現(xiàn)多級聯(lián)動菜單效果
開發(fā)中,有好多地方用到聯(lián)動菜單,以前每次遇到聯(lián)動菜單的時候都去重新寫,代碼重用率很低,前幾天又遇到聯(lián)動菜單的問題,總結(jié)了下,發(fā)現(xiàn)可以開發(fā)一個聯(lián)動菜單的功能,以后想用的時候就方便多了。項目中每個頁面都有引用jQuery,,開發(fā)個jQuery聯(lián)動菜單插件,說動手就動手,下面跟大家分享分享。
我用的jQuery插件方式
(function($){
$.fn.casmenu=function(argvs){
//your code
}
})(jQuery);
其中jQuery傳入的是jquery對象,需要在擴展之前引用。在擴展中同樣使用jQuery的短格式$。
$.fn是指jquery的命名空間,加在fn上的方法及屬性,會對jquery實例每一個有效,看看下面的jquery源碼101行左右:
jQuery.fn = jQuery.prototype = {
......
}
比如說后面要開發(fā)的$.fn.casmenu(),定義之后,在后面的jquery對象都可以使用該方法。
這里還有一種擴展的方法:
$.extend({
funName: function(){
//your code
},
});
這種擴展方法和上面的是有區(qū)別的,要是拿類做類比的話,$.extend這種方法相當(dāng)于類中的靜態(tài)方法,上面的一種方式相當(dāng)于非靜態(tài)方法,必須有對象才可以使用。簡單的理解,是下面這樣的:
//$.fn.casemenu 方式擴展的方法,必須在有jquery對象的時候才可以使用
$("#mydiv").casmenu();
//$.extend({}) 方式擴展的方法,可以直接使用
$.add(2,3);
設(shè)計思路
首先是層級菜單的數(shù)據(jù)保存方式,看看下面的數(shù)據(jù):
var levels={
//內(nèi)容中有引號,必須使用單引號,外引號必須用雙引號
//name => value
1:{
退出應(yīng)用: "code1003",
登錄界面:"code1004",
跳轉(zhuǎn)至個人資料界面:"code1005",
},
2:{
退出應(yīng)用:{
應(yīng)用1:"gameid1",
應(yīng)用2:"gameid2",
應(yīng)用3:"gameid3",
應(yīng)用4:"gameid4",
應(yīng)用5:"gameid5",
},
跳轉(zhuǎn)至個人資料界面:{
主界面:"main interface",
}
},
3:{
應(yīng)用1:{
中級場:"12",
高級場:"13",
職業(yè)場:"14",
比賽場:"15",
}
}
}
對象levels中的直接鍵值1、2、3代表菜單的層級,沒有就不用些,每一項name=>value代表select中option的名稱和value。
層級有規(guī)律,某一層級中的某一項要是有下一級菜單,在下一層及有該項的名稱,就像levels[1]['退出應(yīng)用']在有下級菜單,就有l(wèi)evels[2]['退出應(yīng)用'],要是繼續(xù)有下級菜單,就像levels[2]['退出應(yīng)用']['應(yīng)用1'],會在下一層及中繼續(xù)有l(wèi)evels[3]['應(yīng)用1']。這樣一來,就實現(xiàn)了無限級聯(lián)動菜單,不同的聯(lián)動菜單只需要修改菜單配置文件就可以了。
但是這么做又有一個遺憾,就是如果level2[2]中的子項有兩個名稱相同的,都有下級菜單,而且下級菜單內(nèi)容還不一樣,就會有問題,因此在設(shè)置的時候,有下級菜單的項要取不同的名稱,這里要注意下。就目前這種來說,簡單,好理解,也夠用了。
代碼實現(xiàn)
在代碼中也用到了$.extend,用來擴展默認配置。
還有一個點要注意,在聯(lián)動的時候會將實事的菜單值放入一個屬性為hidden的input中,用默認逗號分割每個層級之間的值,可以很輕松的獲取到聯(lián)動菜單所有項的值
if(typeof(AI.opts.saveinput) != "undefined" && (AI.opts.saveinput = AI.opts.saveinput.toString()) != ''){
$("<input type='hidden' value='' name='"+AI.opts.saveinput+"' id='"+AI.opts.saveinput+"' />").appendTo($('body'));
}
(function($){
//配置
var AI={
opts:{
saveinput:"jumpcode", //是否將結(jié)果保存至input
levels:{},
ulObj:{},//保存生成好的ul列表
length:0, //層級菜單的層級
divide:",",//默認各個層級菜單之間的分隔符
}
};
$.fn.casmenu=function(opts){
AI.opts = $.extend(AI.opts, opts);
if((AI.opts.length = Object.keys(AI.opts.levels).length) <= 0){
throw "levels arr must not be empty";
return;
}
var _levels = AI.opts.levels;
if(_levels[1] == undefined){
throw "menu level 1 must not be empty";
return;
}
var _levels_1 = _levels[1];
if(typeof(AI.opts.saveinput) != "undefined" && (AI.opts.saveinput = AI.opts.saveinput.toString()) != ''){
$("<input type='hidden' value='' name='"+AI.opts.saveinput+"' id='"+AI.opts.saveinput+"' />").appendTo($('body'));
}
AI.opts.ulObj['level_1'] = '<select class="casmenu" level="1">';
AI.opts.ulObj['level_1'] += '<option value="null">請選擇</option>';
$("#"+AI.opts.saveinput).val('null');
for(var i in _levels_1){
AI.opts.ulObj['level_1'] += '<option name="'+i+'" value="'+_levels_1[i]+'">'+i+'</option>';
}
AI.opts.ulObj['level_1'] += '</select>';
$(AI.opts.ulObj['level_1']).appendTo(this);
$("body").on("change", ".casmenu", function(){
var level = $(this).attr("level");
if(level > AI.opts.length) return;
level++;
//移除當(dāng)前觸發(fā)菜單之后的菜單
for(var num=level;num<=AI.opts.length;num++){
$(".casmenu[level="+num+"]").remove();
}
//設(shè)置input的值,級聯(lián)菜單的值
var _val = '';
for(var val=1;val<=AI.opts.length;val++){
var __val = $("select[level="+val+"]");
if(__val.length <= 0)
continue;
_val += __val.val()+AI.opts.divide;
}
$("#"+AI.opts.saveinput).val(_val.substr(0, _val.length-1));
//levels對象中不存在下一級別目錄
if(typeof(AI.opts.levels[level]) == "undefined") return;
//獲取下一級別目錄的鍵值,值不存在的話返回
var name = $(this).find("option:selected").attr("name");
if(typeof(AI.opts.levels[level][name]) == "undefined") return;
if(typeof(AI.opts.ulObj['level_'+level]) == "undefined" || typeof(AI.opts.ulObj['level_'+level][name]) == "undefined"){
if(typeof(AI.opts.ulObj['level_'+level]) == "undefined")
AI.opts.ulObj['level_'+level] = {};
AI.opts.ulObj['level_'+level][name] = '<select class="casmenu" level="'+level+'">';
AI.opts.ulObj['level_'+level][name] += '<option value="null">請選擇</option>';
var levelinfo = AI.opts.levels[level][name];
for(var i in levelinfo){
AI.opts.ulObj['level_'+level][name] += '<option name="'+i+'" value="'+levelinfo[i]+'" >'+i+'</option>';
}
AI.opts.ulObj['level_'+level][name] += '</select>';
}
$(AI.opts.ulObj['level_'+level][name]).appendTo($(this).parent());
var _val = '';
for(var val=1;val<=AI.opts.length;val++){
var __val = $("select[level="+val+"]");
if(__val.length <= 0)
continue;
_val += __val.val()+AI.opts.divide;
}
$("#"+AI.opts.saveinput).val(_val.substr(0, _val.length-1));
});
}
})(jQuery);
運行效果:


以上就是為大家分享的jQuery插件實現(xiàn)多級聯(lián)動菜單效果,希望對大家的學(xué)習(xí)有所幫助。
相關(guān)文章
jquery創(chuàng)建并行對象或者合并對象的實現(xiàn)代碼
如果有對象A ,B 現(xiàn)在我想要合并成對象C 從C里面可以找到A , B 及其子對象 怎么做2012-10-10
JQuery實現(xiàn)動態(tài)添加刪除評論的方法
這篇文章主要介紹了JQuery實現(xiàn)動態(tài)添加刪除評論的方法,涉及jQuery處理鼠標(biāo)事件及json數(shù)據(jù)的相關(guān)技巧,需要的朋友可以參考下2015-05-05
從零開始學(xué)習(xí)jQuery (十) jQueryUI常用功能實戰(zhàn)
本文是實戰(zhàn)篇. 使用jQueryUI完成制作網(wǎng)站的大部分常用功能.2011-02-02
jQuery滾動監(jiān)聽實現(xiàn)商城樓梯式導(dǎo)航效果
這篇文章主要介紹了jQuery滾動監(jiān)聽,實現(xiàn)商城樓梯式導(dǎo)航,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-03-03

