利用Jquery封装下拉选择框,用class封装
1、创建class类:
class SiteSelect {
constructor(configParams) {
this.boxId = configParams.boxId
this.list = configParams.list
this.showField = configParams.showField
this.idField = configParams.idField
this.childListField = configParams.childListField
this.labelField = configParams.labelField
this.placeholder = configParams.placeholder || '请选择'
this.borderRadius = configParams.borderRadius || '25px'
this.width = configParams.width || '100%'
this.height = configParams.height || '50px'
this.borderColor = configParams.borderColor || '#f2f3f5'
this.callBack = configParams.cb
this.createDOM()
this.bindEvents()
this.queryLiEvent()
}
createDOM() {
var boxId = "'" + this.boxId + "'"
var listDoms =
'<span class="select-label" style="line-height:' +
this.height +
'">' +
this.labelField +
'</span>' +
'<div class="select-list" style="width: ' +
this.width +
'; height: ' +
this.height +
'; border-color: ' +
this.borderColor +
'; position: relative;">' +
'<div class="select-down-up select-up" style="width: ' +
this.height +
'; height: ' +
this.height +
';" onclick="SiteSelect.downUpEvent(event, ' +
boxId +
')"></div>' +
'<input type="text" style="border-radius:' +
this.borderRadius +
'" oninput="SiteSelect.filterList(event,' +
boxId +
')" onfocus="SiteSelect.focusInput(event, ' +
boxId +
')" class="select_list_filter" placeholder="' +
this.placeholder +
'" />' +
'<ul class="select-list-box" style="width: ' +
this.width +
'">' +
this.liDoms(this.list) +
'</ul>' +
'</div>'
$('#' + this.boxId).append(listDoms)
}
// 递归创建下拉框的dom节点
liDoms(list) {
var self = this
var liDomsList = ''
function renderItem(item, prefix) {
var itemId = item[self.idField]
var itemName = item[self.showField]
if (!itemId || !itemName) {
return
}
liDomsList += '<li class="select-list-item" id="' + itemId + '" title="' + itemName + '">' + prefix + '' + itemName + '</li>'
if (item.hasChild && Array.isArray(item[self.childListField])) {
item[self.childListField].forEach(function (child) {
return renderItem(child, prefix + '--')
})
}
}
list.forEach(function (item) {
return renderItem(item, '--')
})
return liDomsList
}
// 给下拉框绑定点击事件
queryLiEvent() {
var that = this
var targetDom = $('#' + that.boxId).find('.select-list-box')[0]
targetDom.addEventListener('click', function (e) {
if (e.target == targetDom && targetDom.contains(e.target)) return
var itemName = e.target.title
var itemid = e.target.id
$('#' + that.boxId)
.find('.select_list_filter')
.val(itemName)
$('#' + that.boxId).find('.select-list-box')[0].style.height = '0px'
$('#' + that.boxId)
.find('.select-down-up')[0]
.classList.remove('select-down')
$('#' + that.boxId)
.find('.select-down-up')[0]
.classList.add('select-up')
that.callBack && that.callBack(e, itemid)
})
}
// 点击下拉框以外的区域,下拉框关闭
bindEvents() {
var self = this
document.addEventListener('click', function (e) {
var dropdown = $('#' + self.boxId).find('.select-list-box')[0]
var dropdown1 = $('#' + self.boxId)[0]
var selectDom = $('#' + self.boxId).find('.select-down-up')[0]
if (e.target !== dropdown && !dropdown.contains(e.target) && e.target !== dropdown1 && !dropdown1.contains(e.target)) {
dropdown.style.height = '0px'
selectDom.classList.remove('select-down')
selectDom.classList.add('select-up')
}
})
}
// 下拉框展示收起的事件
static downUpEvent(e, boxId) {
var selectBtnDom = $('#' + boxId).find('.select-list-box')[0]
if (e.target.classList.value.indexOf('select-up') > -1) {
e.target.classList.remove('select-up')
e.target.classList.add('select-down')
selectBtnDom.style.height = '400px'
} else if (e.target.classList.value.indexOf('select-down') > -1) {
e.target.classList.remove('select-down')
e.target.classList.add('select-up')
selectBtnDom.style.height = '0px'
}
}
// input框获取焦点的事件
static focusInput(e, boxId) {
var selectDownDom = $('#' + boxId).find('.select-down-up')[0]
if (selectDownDom.classList.value.indexOf('select-up') > -1) {
selectDownDom.classList.remove('select-up')
selectDownDom.classList.add('select-down')
$('#' + boxId).find('.select-list-box')[0].style.height = '400px'
}
}
// 防抖函数
debounceEve(func, delay) {
var timeoutId
return function () {
var context = this
var args = arguments
clearTimeout(timeoutId)
timeoutId = setTimeout(function () {
func.apply(context, args)
}, delay)
}
}
// 过滤下拉列表--只是隐藏显示控制,不改变数据
filterMethod(e, boxId) {
var inputVal = e.target.value
var listItems = $(`#${boxId}`).find('.select-list-item')
listItems.each(function (_, item) {
var isVisible = inputVal ? item.innerText.includes(inputVal) : true
$(item).toggle(isVisible)
})
}
static filterList(e, boxId) {
var debouncedAction = this.prototype.debounceEve(this.prototype.filterMethod, 500)
debouncedAction(e, boxId)
}
}
2、使用
<div id="college_box" style="margin-top: 50px; width: 400px; display: inline-block"></div>
<script>
var data = [
{
id: '1',
name: '计算机科学与技术',
hasChild: true,
childCollegeList: [
{
id: '1-1',
name: '软件工程',
hasChild: true,
childCollegeList: [
{
id: '1-1-1',
name: '软件工程',
hasChild: false,
childCollegeList: [],
},
{
id: '1-2-1',
name: '计算机科学与技术',
hasChild: false,
childCollegeList: [],
},
],
},
{
id: '1-2',
name: '计算机科学与技术',
hasChild: false,
childCollegeList: [],
},
],
}
]
function test(e, id) {
console.log(e, id)
}
var collageConfig = {
boxId: 'college_box', // 容器id
list: data, // 数据源
showField: 'name', // 显示字段
idField: 'id', // id字段
childListField: 'childCollegeList', // 子列表字段
labelField: '学院选择:', // label字段
cb: test, // 点击选项的回调
placeholder: '请选择学院', // placeholder字段
borderRadius: '20px', // 边框圆角
width: '300px', // 宽度
height: '40px', // 高度
borderColor: '#f2f3f5', // 边框颜色
}
var college = new SiteSelect(collageConfig)
</script>
3、一些属性和字段都是可以配置的,想创建几个只需 new SiteSelect()实例,配置对应的属性即可;