今天小編和大家分享有關(guān)于“怎么寫(xiě)B(tài)UI折疊菜單插件?”這個(gè)問(wèn)題的解決方法和代碼解析!希望對(duì)小伙伴們的學(xué)習(xí)有所幫助!
寫(xiě)一個(gè)BUI折疊菜單插件效果預(yù)覽
控件分析控件結(jié)構(gòu)
一個(gè)點(diǎn)擊顯示隱藏的效果, 并且點(diǎn)擊的時(shí)候, 會(huì)先把展開(kāi)進(jìn)行隱藏, 再展開(kāi)自己的. 從界面上我們來(lái)看看結(jié)構(gòu)的設(shè)計(jì).
<!-- 一般控件最外層就是控件的容器名 -->
<div class="bui-foldmenu">
<div class="bui-foldmenu-item">菜單</div>
<div class="bui-foldmenu-content">內(nèi)容</div>
<div class="bui-foldmenu-item">菜單2</div>
<div class="bui-foldmenu-content">內(nèi)容2</div>
</div>
這里我們采用的是并列同級(jí)的方式, 那結(jié)構(gòu)寫(xiě)起來(lái)有點(diǎn)麻煩, 其實(shí)這個(gè)結(jié)構(gòu)跟 dl,dt,dd 是一致的, 那我們完全可以?xún)?yōu)化成以下結(jié)構(gòu).
<!-- 一般控件最外層就是控件的容器名 -->
<dl class="bui-foldmenu">
<dt>菜單</dt>
<dd>內(nèi)容</dd>
<dt>菜單2</dt>
<dd>內(nèi)容2</dd>
</dl>
bui的設(shè)計(jì)是基于按鈕的原型撐開(kāi)容器的方式, 這樣可以保持每個(gè)容器都是一致的標(biāo)準(zhǔn)高度, 所以我們?cè)賹?duì)結(jié)構(gòu)進(jìn)行優(yōu)化.
<!-- 一般控件最外層就是控件的容器名 -->
<dl class="bui-foldmenu">
<dt class="bui-btn">菜單</dt>
<dd>內(nèi)容</dd>
<dt class="bui-btn">菜單2</dt>
<dd>內(nèi)容2</dd>
</dl>
像剛剛效果圖,菜單的點(diǎn)擊還會(huì)有圖標(biāo)的切換, 再結(jié)合布局來(lái)得到以下結(jié)構(gòu), 一切皆布局, 一切皆容器.
<!-- 一般控件最外層就是控件的容器名 -->
<dl class="bui-foldmenu">
<dt class="bui-btn bui-box"><div class="span1">菜單</div><i class="icon-foldmenu"></i></dt>
<dd>內(nèi)容</dd>
<dt class="bui-btn bui-box"><div class="span1">菜單2</div><i class="icon-foldmenu"></i></dt>
<dd>內(nèi)容2</dd>
</dl>
控件樣式
一般作為插件的獨(dú)立樣式引入, bui-foldmenu.css
文件
.bui-foldmenu {}
.bui-foldmenu>dt,
.bui-foldmenu>[class*=bui-btn] {
border: 0;
border-bottom: 1px solid #eee;
}
/* 默認(rèn)隱藏內(nèi)容 */
.bui-foldmenu>dd {
display: none;
border: 0;
overflow-y: auto;
border-bottom: 1px solid #eee;
background: #fff;
}
/* 圖標(biāo) */
.bui-foldmenu .icon-foldmenu {
-webkit-transition: -webkit-transform 0.3s ease-in-out 0s;
transition: transform 0.3s ease-in-out 0s;
}
.bui-foldmenu .icon-foldmenu:before {
content: "e649";
}
/* 激活的時(shí)候顯示block */
.bui-foldmenu>.active+dd {
display: block;
}
/* 激活的二級(jí)菜單的時(shí)候,把箭頭翻轉(zhuǎn) */
.bui-foldmenu>.active .icon-foldmenu {
-webkit-transform: rotate(-180deg);
transform: rotate(-180deg);
}
樣式里面就默認(rèn)隱藏內(nèi)容標(biāo)簽(dt相鄰的dd),由控件初始化, 其它都是一些修飾, 設(shè)置激活狀態(tài)的時(shí)候,箭頭翻轉(zhuǎn).
控件腳本
1.5.4 新增 bui.extend 方法,可以用來(lái)擴(kuò)展插件, 并且保持跟 bui原本的使用方式一致.
bui.extend 控件參數(shù)是一個(gè)對(duì)象, 其中包含以下參數(shù)
name string
控件名稱(chēng)config object
控件默認(rèn)參數(shù)callback function
控件的邏輯最簡(jiǎn)單的版本
// 最簡(jiǎn)單的版本
bui.extend({
name: "foldmenu",
config: {
id: ""
},
callback: function(opt) {
// that 指向插件的拋出的公共方法, option widget 等
let that = this;
// this.config 為已經(jīng)跟初始化參數(shù)合并以后的結(jié)果;
let param = this.config;
// 緩存選擇器
let $id = null;
// 要拋給開(kāi)發(fā)者的方法
that.init = function(option) {
// 對(duì)直接調(diào)用init方法的參數(shù)進(jìn)行合并
param = $.extend(true, {}, param, option);
// 單頁(yè)多頁(yè)選擇器,如果是單頁(yè),這個(gè)插件只能在模塊里面用, 不能在bui.ready
$id = bui.$(param.id);
// 綁定事件,點(diǎn)擊的時(shí)候增加激活樣式
$id.children("dt").click(function(e) {
var hasActive = $(this).hasClass("active");
if (hasActive) {
$(this).removeClass("active");
} else {
// 加上樣式以后會(huì)自動(dòng)對(duì)箭頭及下一層級(jí)展示處理;
$(this).addClass("active");
}
})
return that;
}
// 如果有依賴(lài)bui控件,應(yīng)該在這里寫(xiě),這樣方便外部調(diào)用
// that.widgets.loading = ui.loading({
// appendTo: opt.id
// });
// 如果需要銷(xiāo)毀的生命周期,則在這里加上.
// that.beforeDestroy = function() {
//
// return that;
// }
// 必須傳id
if (!param.id) {
// 拋出錯(cuò)誤
bui.showLog("必須傳id參數(shù).")
return that;
}
// 默認(rèn)先初始化一次
return this.init(opt);
}
});
控件使用
<dl id="folder" class="bui-foldmenu">
<dt class="bui-btn">菜單</dt>
<dd>內(nèi)容</dd>
<dt class="bui-btn">菜單2</dt>
<dd>內(nèi)容2</dd>
</dl>
// 初始化
var uiFloder = bui.foldmenu({id:"#folder"})
// uiFloder.config 可以拿到一些實(shí)例的參數(shù)
插件預(yù)覽
完善插件
用閉包防止全局污染
放在一個(gè)閉包里,這樣可以防止控件受到污染,window.libs
指的是zepto
或者jquery
, 當(dāng)你去掉引入 zepto.js 的時(shí)候, 引入jquery.js
就可以完美切換成jquery版本. (jquery版本建議在: 1.9.x - 1.11.x)
;(function(ui, $) {
"use strict";
})(window.bui || {}, window.libs);
加上注釋
/* @namespace bui
* @class foldmenu
* @constructor
* @param {object} option
* @param {string} option.id [控件id]
* @param {string} [option.handle] [點(diǎn)擊的區(qū)域]
* @param {number} [option.height] [父層高度,0則自適應(yīng)]
* @param {string} [option.target] [要顯示隱藏的目標(biāo)]
* @param {number} [option.targetHeight] [目標(biāo)自適應(yīng)高度還是限制高度]
* @param {boolean} [option.single] [ false(顯示多個(gè)) || true(一次只折疊一個(gè)) ]
* @param {function} [option.onInited] [ 1.5.1新增 初始化以后觸發(fā) ]
* @param {function} [option.callback] [ 點(diǎn)擊按鈕的回調(diào) ]
* @example
*
*/
完整版:
;(function(ui, $) {
"use strict";
/* @namespace bui
* @class foldmenu
* @constructor
* @param {object} option
* @param {string} option.id [控件id]
* @param {string} [option.handle] [點(diǎn)擊的區(qū)域]
* @param {number} [option.height] [父層高度,0則自適應(yīng)]
* @param {string} [option.target] [要顯示隱藏的目標(biāo)]
* @param {number} [option.targetHeight] [目標(biāo)自適應(yīng)高度還是限制高度]
* @param {boolean} [option.single] [ false(顯示多個(gè)) || true(一次只折疊一個(gè)) ]
* @param {function} [option.onInited] [ 1.5.1新增 初始化以后觸發(fā) ]
* @param {function} [option.callback] [ 點(diǎn)擊按鈕的回調(diào) ]
* @example
*
*/
ui.extend({
name: "foldmenu",
config: {
id: ""
},
callback: function(opt) {
// that 指向插件的拋出的公共方法, option widget 等
let that = this;
// this.config 為已經(jīng)跟初始化參數(shù)合并以后的結(jié)果;
let param = this.config;
// 緩存選擇器
let $id = null;
// 要拋給開(kāi)發(fā)者的方法
that.init = function(option) {
// 對(duì)直接調(diào)用init方法的參數(shù)進(jìn)行合并
param = $.extend(true, {}, param, option);
// 單頁(yè)多頁(yè)選擇器,如果是單頁(yè),這個(gè)插件只能在模塊里面用, 不能在bui.ready
$id = ui.$(param.id);
// 綁定事件,點(diǎn)擊的時(shí)候增加激活樣式
$id.children("dt").click(function(e) {
var hasActive = $(this).hasClass("active");
if (hasActive) {
$(this).removeClass("active");
} else {
// 加上樣式以后會(huì)自動(dòng)對(duì)箭頭及下一層級(jí)展示處理;
$(this).addClass("active");
}
})
return that;
}
// 如果有依賴(lài)bui控件,應(yīng)該在這里寫(xiě),這樣方便外部調(diào)用
// that.widgets.loading = ui.loading({
// appendTo: opt.id
// });
// 如果需要銷(xiāo)毀的生命周期,則在這里加上.
// that.beforeDestroy = function() {
//
// return that;
// }
// 必須傳id
if (!param.id) {
// 拋出錯(cuò)誤
ui.showLog("必須傳id參數(shù).")
return that;
}
// 默認(rèn)先初始化一次
return this.init(opt);
}
});
})(window.bui || {}, window.libs);
結(jié)語(yǔ)
那么上面我們分享的內(nèi)容就是有關(guān)于“怎么寫(xiě)B(tài)UI折疊菜單插件?”這方面的相關(guān)內(nèi)容分享!更多有關(guān)于html5這個(gè)方面的學(xué)習(xí)我們都可以在W3Cschool中進(jìn)行學(xué)習(xí)!以上我們展示的是一個(gè)最簡(jiǎn)單的插件的開(kāi)發(fā)及使用, 但插件的適應(yīng)性還不夠, 還需要考慮各種擴(kuò)展性,復(fù)雜的場(chǎng)景如何去適應(yīng), 比方內(nèi)容是需要固定高度,選擇器換成其它,只展示一個(gè),等各種需求都不能滿(mǎn)足, 我們需要考慮更多的場(chǎng)景, 抽取更多的變量作為可配置.希望小編的分享對(duì)大家有所幫助!