效果
方法
- 两个步骤,初始化界面, 交互事件
- 将所有的样式写好,包括动画,后期添加类
- html 包含三个select,每个select展现不提供的数据
- 默认后面的div 是不可选中的
- 保存好上次的数据,传递下次使用
结构
初始化
初始化阶段,默认数据的填充,和每个状态的管理(是否可点击)
写好html,css 将数据填充到ProvinceDiv
里面
fillSelect(doms.selProvince, datas); // 接受两个参数,填充的div和数据
fillSelect(doms.selCity, []);
fillSelect(doms.selArea, []);
// 如果没有填充的数据将状态设置为disabled
function fillSelect(select, list) {
select.className = `select ${list.length ? '' : 'disabled'}`;
const tipName = select.dataset.name;
const span = select.querySelector('span');
span.innerText = '请选择' + tipName;
// 精髓:解决数据传递问题
// 将本次使用的数据保存,下次接着这个数据筛选
select.datas = list;
const ul = select.querySelector('ul');
ul.innerHTML = list.map((e) => { return `<li>${ e.label}</li>`}).join("");
}
交互事件
- 单击div事件,显示二级菜单
- 二级菜单选中toggle样式
select
绑定不同的渲染数据时间.
regCommonEvent(doms.selProvince);
regCommonEvent(doms.selCity);
regCommonEvent(doms.selArea);
// 注册三个公共事件
// div都需要展开二级菜单,和菜单项
function regCommonEvent(select) {
const title = select.querySelector('.title');
// title 点击事件
title.addEventListener('click', () => {
// 禁用状态下无法操作
if (select.classList.contains('disabled')) {
return;
}
const expands = select.querySelectorAll('.select.expand');
for (const el of expands) {
el.classList.remove('expand');
}
select.classList.toggle('expand');
});
const ul = select.querySelector('.options');
// ul事件
ul.addEventListener('click', (e) => {
if (e.target.tagName !== 'LI') {
return;
}
const beforeActiveLi = select.querySelector('li.active');
beforeActiveLi && beforeActiveLi.classList.remove('active');
const li = e.target;
li.classList.add('active');
const span = select.querySelector('span');
span.innerText = e.target.innerText;
});
//鼠标移除隐藏二级菜单
ul.addEventListener('mouseleave', () => {
select.classList.remove('expand');
});
}
数据渲染
//给省div绑定事件,将数据渲染到城市div
function regProvinceEvent() {
const ul = doms.selProvince.querySelector('.options');
ul.addEventListener('click', (e) => {
let li = e.target;
if (li.tagName !== 'LI') {
return
}
const pr = doms.selProvince.datas.find((e) => {
return e.label === li.innerText;
});
//渲染到城市
fillSelect(doms.selCity, pr.children);
//将地区div,disabled
fillSelect(doms.selArea, []);
});
}
//给城市div绑定事件,将数据渲染到地区div
function regCityEvent() {
const ul = doms.selCity.querySelector('.options');
ul.addEventListener('click', (e) => {
let li = e.target;
if (li.tagName !== 'LI') {
return;
}
const pr = doms.selCity.datas.find((e) => {
return e.label === li.innerText;
});
//渲染到地区
fillSelect(doms.selArea, pr.children);
});
}