javascript模擬select,jselect的方法實現
2024-05-06 14:21:00
供稿:網友
由于主流瀏覽器對select元素渲染不同,所以在每種瀏覽器下顯示也不一樣,最主要的是默認情況下UI太粗糙,即使通過css加以美化也不能達到很美觀的效果。這對于我們這些專注于UX的前端開發人員是無法容忍的。于是在項目不太忙的時候,就計劃寫一個模擬的select控件出來。接下來就把實現的細節、遇到的問題以及如何使用和大家分享一下。
1. 實現細節
init: function(context) {
//獲取指定上下文所有select元素
var elems = squid.getElementsByTagName('select', context)
this.globalEvent()
this.initView(elems)
}
在一個用戶注冊的應用場景,有多個select元素。模擬的select控件(以下簡稱jselect)初始化方法會獲取頁面上所有select元素,然后綁定全局事件globalEvent,初始化頁面顯示initView。globalEvent方法如下:
代碼如下:
globalEvent: function() {
//document 添加click事件,用戶處理每個jselect元素展開關閉
var target,
className,
elem,
wrapper,
status,
that = this;
squid.on(document, 'click', function(event) {
target = event.target,
className = target.className;
switch(className) {
case 'select-icon':
case 'select-default unselectable':
elem = target.tagName.toLowerCase() === 'div' ? target : target.previousSibling
wrapper = elem.nextSibling.nextSibling
//firefox 鼠標右鍵會觸發click事件
//鼠標左鍵點擊執行
if(event.button === 0) {
//初始化選中元素
that.initSelected(elem)
if(squid.isHidden(wrapper)) {
status = 'block'
//關閉所有展開jselect
that.closeSelect()
}else{
status = 'none'
}
wrapper.style.display = status
elem.focus()
}else if(event.button === 2){
wrapper.style.display = 'none'
}
that.zIndex(wrapper)
break
case 'select-option':
case 'select-option selected':
if(event.button === 0) {
that.fireSelected(target, target.parentNode.parentNode.previousSibling.previousSibling)
wrapper.style.display = 'none'
}
break
default:
while(target && target.nodeType !== 9) {
if(target.nodeType === 1) {
if(target.className === 'select-wrapper') {
return
}
}
target = target.parentNode
}
that.closeSelect()
break
}
})
}
globalEvent實現了在document綁定click事件,然后在頁面上觸發點擊事件的時候通過事件代理來判斷當前點擊元素是否是需要進行處理的目標元素,判斷條件是通過元素的class,代碼中語句的分支分別是:展開當前點擊的jselect元素下拉、選中點擊列表項、判斷是否需要關閉jselect。
initView方法如下:
代碼如下:
initView: function(elems) {
var i = 0,
elem,
length = elems.length,
enabled;
for(; i < length; i++) {
elem = elems[i]
enabled = elem.getAttribute('data-enabled')
//使用系統select