JS樹形菜單組件Bootstrap TreeView使用方法詳解
簡要介紹:
之前手頭的一個項目需要去做一個左側(cè)的樹形菜單,右側(cè)則是一個整體的iframe,從而構(gòu)成一個整體的網(wǎng)站。一開始是打算用bootstrap的tree-view插件,直接把菜單的數(shù)據(jù)傳過去就好了,結(jié)果后來項目又改了需求,菜單的內(nèi)容和圖表都是后臺動態(tài)生成的,所以只能放棄使用bootstrap插件,自己著手寫了一個樹形菜單。本文主要分兩部分講,一個是對于bootstrap的treeview的實踐,另一部分是介紹自己寫的樹形菜單。
bootstrap-treeview:
組件介紹:http://www.dbjr.com.cn/article/96222.htm
其實關(guān)于該組件在其他網(wǎng)站上已經(jīng)講得很詳細了,我就不再贅述了,但是網(wǎng)上的應(yīng)用還是有點問題,這里主要講一下自己使用這個插件過程吧。
1. html引用及結(jié)構(gòu)
引用css:文件本身的css文件、bootstrp.css文件
引用js:jquery、bootstrap-treeview.js、引用該組件的treeview.js文件
整體HTML結(jié)構(gòu)主要分為了三個部分:頭部、樹狀欄部分、iframe部分,使用組件的為樹狀欄部分:#tree

2.引用組件js設(shè)置:
具體設(shè)置代碼如下:主要思路是用data傳入菜單的數(shù)據(jù)和依靠關(guān)系,同時可以設(shè)置一些變量來控制改樹狀欄的樣式和基本功能,如代碼40-43行,具體變量對應(yīng)的數(shù)值的意義可以參見之前鏈接中的表格
(function(win) {
var data = [
{
text: "Parent 1",
nodes: [
{
text: "Child 1",
nodes: [
{
text: "Grandchild 1"
},
{
text: "Grandchild 2"
}
]
},
{
text: "Child 2"
}
]
},
{
text: "Parent 2"
},
{
text: "Parent 3"
},
{
text: "Parent 4"
},
{
text: "Parent 5"
}
];
var tree = function() {
$('#tree').treeview({
data: data,
backColor: '#293541',
color: 'white',
onhoverColor:'#202a33;',
showBorder: false
});
}
var init = function() {
tree();
}
init();
})(window)
設(shè)置完成之后樹狀欄的樣式如下圖所示,另外細節(jié)方面可以通過閱讀相應(yīng)參數(shù)來設(shè)置,值得一提的是樹狀欄的icon圖標(biāo)是通過bootstrap的glyphicon設(shè)置的,有興趣的童鞋可以去看一下這個東西,來為菜單設(shè)置不同的icon,不過實際效果感覺不是特別好。這也是我決定自己去搞一個樹狀欄的原因。
自定義樹狀菜單:
treeview的插件只能點擊菜單前面的加號icon展開關(guān)閉,樣式的變化有限,而且我們需要根據(jù)后臺傳入的數(shù)據(jù)來動態(tài)設(shè)置菜單的結(jié)構(gòu)和內(nèi)容,所以為了滿足這幾個需求,重新寫了一個tree.js
js主要分成三個部分,第一個部分是為每個菜單和子菜單注冊點擊事件以及通過后臺傳來的數(shù)據(jù)為其綁定跳轉(zhuǎn)鏈接;第二個部分是通過ajax獲取后臺傳來的菜單數(shù)據(jù),并將數(shù)據(jù)傳入前臺;第三個部分是通過underscore的template函數(shù)將前臺頁面進行渲染,達到動態(tài)實現(xiàn)樹狀欄的功能。、
相關(guān)js代碼:
var tree = function() {
//一級導(dǎo)航點擊事件
$('.nodeBox').on('click', function(event) {
var _this = $(this);
var child = _this.parent().find('.nodechild_box');
if (_this.attr('opened') == 'opened') {
_this.parent().find('.childnode').hide();
child.hide();
_this.attr('opened', '');
}else{
_this.parent().find('.childnode').show();
child.show();
_this.attr('opened', 'opened');
};
});
//二級導(dǎo)航點擊事件
$('.nodechild_box').on('click', function(event) {
var _this = $(this);
var child = _this.parent().find('.gchild_box');
if (_this.attr('opened') == 'opened') {
child.hide();
_this.parent().find('.gchildnode').hide();
_this.find('.add').attr('src', 'images/icon_add.png');
_this.attr('opened', '');
}else{
child.show();
_this.parent().find('.gchildnode').show();
_this.find('.add').attr('src', 'images/icon_minus.png');
_this.attr('opened', 'opened');
};
});
//三級導(dǎo)航點擊事件
$('.gchild_box').on('click', function(event) {
var _this = $(this);
var child = _this.parent().find('.ggchild_box');
if (_this.attr('opened') == 'opened') {
child.hide();
_this.find('.add').attr('src', 'images/icon_add.png');
_this.attr('opened', '');
}else{
child.show();
_this.find('.add').attr('src', 'images/icon_minus.png');
_this.attr('opened', 'opened');
};
});
//hover顯示箭頭及背景變化
$('.nodeBox').mouseover(function(event) {
$(this).addClass('tree_hover');
$(this).find('.arrow').show();
});
$('.nodeBox').mouseout(function(event) {
$(this).removeClass('tree_hover');
$(this).find('.arrow').hide();
});
$('.nodechild_box').mouseover(function(event) {
$(this).addClass('box_hover');
$(this).find('.arrow').show();
});
$('.nodechild_box').mouseout(function(event) {
$(this).removeClass('box_hover');
$(this).find('.arrow').hide();
});
$('.gchild_box').mouseover(function(event) {
$(this).addClass('box_hover');
$(this).find('.arrow').show();
});
$('.gchild_box').mouseout(function(event) {
$(this).removeClass('box_hover');
$(this).find('.arrow').hide();
});
$('.ggchild_box').mouseover(function(event) {
$(this).addClass('box_hover');
$(this).find('.arrow').show();
});
$('.ggchild_box').mouseout(function(event) {
$(this).removeClass('box_hover');
$(this).find('.arrow').hide();
});
};
//鏈接函數(shù)
var tree_link = function() {
var linkBox = $('[menurl]');
linkBox.each(function(i, ele) {
var _ele = $(ele);
var key = _ele.attr('menurl');
if(key != '/'){
$(this).on('click',function(){
$('#mainweb').attr('src', key);
auto();
})
}
});
};
//獲取登陸用戶數(shù)據(jù)
var getData = function() {
var cond = sessionStorage.cond;
$.post("XXXX", {}, function(json) {
console.log(json)
if(json.code == 200){
data = json.data;
fillUserName(data);
fillTree(data);
var length = $('.nodeBox').length ;
for (var i = 0;i < length;i++) {
var iconId = data.icons[i].iconId;
$('.nodeBox').eq(i+1).attr('menuid',i);
$('.nodeBox').eq(i+1).find('img').attr('src','images/'+ data.icons[iconId-1].name +'');
}
//為每個菜單添加鏈接
tree_link()
}
}, function(xhr) {
console.log(xhr)
});
}
var fillTree = function(data){
var tmplDom = $('#tree');
tmplDom.parent().html(eking.template.getHtml(tmplDom.html(),data));
tree();
}
HTML渲染:
<div class="main w_1200">
<div class="tree">
<script type="text/html" id="tree">
<div class="tree_box">
<div class="nodeBox index" menurl="notice.html">
<span class="m_l_10"><img src="images/icon_home.png" alt=""></span>
<span class="m_l_10">首頁</span>
<span class="arrow fr m_r_10"><img src="images/icon_arrow.png" alt=""></span>
</div>
</div>
<%var menus = data.menus;%>
<%for(var i = 0;i < menus.length;i++){%>
<div class="tree_box">
<div class="nodeBox" menurl=<%=menus[i].url%> >
<span class="m_l_10"><img src="" alt=""></span>
<span class="m_l_10"><%=menus[i].name%></span>
</div>
<%var childmenus = menus[i].childs;%>
<%for(var j = 0;j < childmenus.length;j++){%>
<div class="childnode">
<div class="nodechild_box" menurl=<%=childmenus[j].url%> >
<%if(childmenus[j].childs.length != 0){%>
<span class="m_l_20"><img class="add" src="images/icon_add.png" alt=""></span>
<span class="m_l_10"><%=childmenus[j].name%></span>
<%}else{%>
<span class="m_l_55"><%=childmenus[j].name%></span>
<span class="arrow fr m_r_10"><img src="images/icon_arrow.png" alt=""></span>
<%}%>
</div>
<%var cchildmenus = childmenus[j].childs;%>
<%for(var k = 0;k < cchildmenus.length;k++){%>
<div class="gchildnode">
<div class="gchild_box" menurl=<%=cchildmenus[k].url%> >
<%if(cchildmenus[k].childs.length != 0){%>
<span class="m_l_30"><img class="add" src="images/icon_add.png" alt=""></span>
<span class="m_l_10"><%=cchildmenus[k].name%></span>
<%}else{%>
<span class="m_l_65"><%=cchildmenus[k].name%></span>
<span class="arrow fr m_r_10"><img src="images/icon_arrow.png" alt=""></span>
<%}%>
</div>
<%var ccchildmenus = cchildmenus[k].childs;%>
<%for(var l = 0;l < ccchildmenus.length;l++){%>
<div class="ggchild_box" menurl=<%=ccchildmenus[l].url%> >
<span class="m_l_70"><%=ccchildmenus[l].name%></span>
<span class="arrow fr m_r_10"><img src="images/icon_arrow.png" alt=""></span>
</div>
<%}%>
</div>
<%}%>
</div>
<%}%>
</div>
<%}%>
</script>
</div>
后臺傳入的數(shù)據(jù)格式為

菜單效果如圖:

存在的不足和問題:
為了跟上項目進度,tree.js尚未組件化,等有時間了打算把這一塊封裝為一個js組件,通過設(shè)置參數(shù)完成樹狀欄的設(shè)置。
P.S.由于個人技術(shù)水平有限,難免出現(xiàn)錯誤,請多多指正 :)
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android TreeView實現(xiàn)帶復(fù)選框樹形組織結(jié)構(gòu)
- 對Python 窗體(tkinter)樹狀數(shù)據(jù)(Treeview)詳解
- bootstrap treeview 樹形菜單帶復(fù)選框及級聯(lián)選擇功能
- WPF自定義TreeView控件樣式實現(xiàn)QQ聯(lián)系人列表效果
- Bootstrap treeview實現(xiàn)動態(tài)加載數(shù)據(jù)并添加快捷搜索功能
- Android UI 之實現(xiàn)多級樹形列表TreeView示例
- Bootstrap樹形菜單插件TreeView.js使用方法詳解
- 淺析BootStrap Treeview的簡單使用
- GTK treeview原理及使用方法解析
相關(guān)文章
js實現(xiàn)完全自定義可帶多級目錄的網(wǎng)頁鼠標(biāo)右鍵菜單方法
這篇文章主要介紹了js實現(xiàn)完全自定義可帶多級目錄的網(wǎng)頁鼠標(biāo)右鍵菜單方法,實例分析了javascript實現(xiàn)自定義網(wǎng)頁鼠標(biāo)右鍵彈出菜單的技巧,非常具有實用價值,需要的朋友可以參考下2015-02-02
openlayers實現(xiàn)圖標(biāo)拖動獲取坐標(biāo)
這篇文章主要為大家詳細介紹了openlayers實現(xiàn)圖標(biāo)拖動獲取坐標(biāo),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-09-09
JavaScript Ajax Json實現(xiàn)上下級下拉框聯(lián)動效果實例代碼
這篇文章主要介紹了JavaScript Ajax Json實現(xiàn)上下級下拉框聯(lián)動效果實例代碼,有需要的朋友可以參考一下2013-11-11

