源代码
class selectTree {
elem;
elemShow;
elemMain;
elemShowOption;
optionHtml = [];
nameFiled;
valueFiled;
i
constructor(option) {
this.elem = $(option.elem);
this.nameFiled = option.name || 'name'
this.valueFiled = option.value || 'value'
this.buildMain();
}
build(data) {
this.optionHtml = [];
this.buildOption(data, 15)
this.elemShowOption.html(this.optionHtml.join(''))
this.buildOptionCSSEvent()
let value = this.elem.val()
if (!value) {
value = data[0] ? data[0][this.valueFiled] : ''
}
let val = this.elemShowOption.find('div[tag-data="' + value + '"]');
let parents = val.parents('dd');
let scroll = 0;
parents.each(function (k, v) {
$(v).children(':first').find('div').click()
scroll += $(v).prevAll().length * 36
})
this.elemShowOption.css({visibility:'hidden'})
val.click()
var _this = this
setTimeout(function () {
_this.elemShowOption.scrollTop(scroll)
_this.elemShowOption.hide()
_this.elemShowOption.css({visibility:'visible'})
}, 500)
this.i.css({transform: 'rotate(0deg)', marginTop: '-3px',})
this.i.i = 1
}
buildMain() {
var _this = this
this.elem.after('<div tag="selectTree-main" style="position:relative;display: inline-block;"></div>')
this.elemMain = this.elem.next()
this.elemMain.append('<input name="selectTreeNameShow"/>')
this.elemShow = this.elemMain.find('input[name=selectTreeNameShow]')
this.elemMain.append(this.elem)
this.elemMain.append('<i></i>')
let i = this.elem.next()
this.i = i
this.elem.hide();
this.elemShow.css({
height: '38px',
width: '100%',
lineHeight: '1.3',
border: '1px solid #e6e6e6',
borderRadius: '2px',
backgroundColor: '#fff',
paddingRight: '30px',
paddingLeft: '10px',
cursor: 'pointer',
})
this.elemShow.prop('readonly', true)
i.css({
width: 0,
height: 0,
border: '7px solid transparent',
borderTopColor: '#c2c2c2',
position: 'absolute',
right: '10px',
top: (this.elemShow.height() / 2 + "px"),
marginTop: '-3px',
transition: 'all .3s'
})
this.elemShow.click(function () {
i.i = 0;
return function () {
if (i.i) {
i.css({transform: 'rotate(180deg)', marginTop: '-9px'})
} else {
i.css({transform: 'rotate(0deg)', marginTop: '-3px',})
}
i.i = !i.i;
_this.elemShowOption.slideToggle(200);
return false;
}
}())
this.elemMain.append('<div tag="show-option"></div>')
this.elemShowOption = this.elemMain.find('div[tag=show-option]')
this.elemShowOption.css({
minWidth: '100%',
maxHeight: '300px',
position: 'absolute',
top: (this.elemShow.height() + 5 + "px"),
backgroundColor: '#ffffff',
zIndex: 9999,
display: 'none',
overflowY: 'auto',
border: '1px solid #ccc',
})
}
buildOption(data, paddingLeft) {
const _this = this;
this.optionHtml.push('<dl>')
$(data).each(function (k, v) {
_this.optionHtml.push('<dd><div tag-data="' + v[_this.valueFiled] + '">');
if (v.children && v.children.length > 0) {
_this.optionHtml.push('<div style="padding-left: ' + paddingLeft + 'px;display: inline-block">');
_this.optionHtml.push('<i></i>');
} else {
_this.optionHtml.push('<div style="padding-left: ' + (paddingLeft + 10) + 'px;display: inline-block"> ');
}
_this.optionHtml.push('</div><span>' + v[_this.nameFiled] + '</span></div>');
if (v.children && v.children.length > 0) {
_this.buildOption(v.children, paddingLeft + 15)
}
_this.optionHtml.push('</dd>');
})
this.optionHtml.push('</dl>')
}
buildOptionCSSEvent() {
const _this = this;
let div = this.elemShowOption.find('dd>div')
this.elemShowOption.find('dd>dl').hide()
let i = this.elemShowOption.find('i')
div.css({
whiteSpace: 'nowrap',
paddingRight: '15px',
lineHeight: '36px',
cursor: 'pointer',
})
div.hover(function () {
$(this).not('.check').css({backgroundColor: '#eee'})
}, function () {
$(this).not('.check').css({backgroundColor: '#ffffff00'})
})
div.click(function () {
div.css({backgroundColor: '#ffffff00', color: '#000'})
div.removeClass('check')
let name = $(this).find('span').html();
let value = $(this).attr('tag-data');
$(this).css({backgroundColor: '#5FB878', color: '#fff'})
$(this).addClass('check')
_this.elem.val(value);
_this.elemShow.val(name)
_this.elemShow.click();
return false;
})
i.css({
width: 0,
height: 0,
border: '7px solid transparent',
borderLeftColor: '#c2c2c2',
position: 'relative',
left: '0px',
transition: 'all .3s',
display: 'inline-block',
})
this.elemShowOption.find('dd>div>div').click(function () {
let a = $(this).attr('unfold') || 'true';
if (a === 'true') {
$(this).find('i').css({transform: 'rotate(90deg)', top: '3px', left: '-3px'})
$(this).attr('unfold', 'false')
} else {
$(this).find('i').css({transform: 'rotate(0deg)', top: '1px', left: '0px'})
$(this).attr('unfold', 'true')
}
$(this).parent().next().slideToggle(200);
return false;
})
}
}
使用方法
<input type="text" name="cate_id" required lay-verify="required" placeholder="请输入标题"
autocomplete="off"
class="layui-input" id="cate">
var select = new selectTree({
elem: '#cate',
name: 'name',//指定展示的名字字段
value: 'id'//指定提交值的字段
});
select.build(selectData)//执行构建选择器
数据结构
let a = [
{
name:'手机',
id:'10',
children:[
{
name:'苹果手机',
id:'20'
}
]
}
];
效果