js实现级联菜单
使用纯JavaScript实现级联菜单
通过监听父级菜单的change事件动态加载子菜单数据

// 获取DOM元素
const provinceSelect = document.getElementById('province');
const citySelect = document.getElementById('city');
const districtSelect = document.getElementById('district');
// 模拟数据
const data = {
'江苏省': ['南京市', '苏州市', '无锡市'],
'浙江省': ['杭州市', '宁波市', '温州市']
};
const cityData = {
'南京市': ['玄武区', '秦淮区', '建邺区'],
'苏州市': ['姑苏区', '虎丘区', '吴中区']
};
// 省份选择变化时触发
provinceSelect.addEventListener('change', function() {
const selectedProvince = this.value;
citySelect.innerHTML = '<option value="">请选择城市</option>';
districtSelect.innerHTML = '<option value="">请选择区县</option>';
if (selectedProvince) {
data[selectedProvince].forEach(city => {
const option = document.createElement('option');
option.value = city;
option.textContent = city;
citySelect.appendChild(option);
});
}
});
// 城市选择变化时触发
citySelect.addEventListener('change', function() {
const selectedCity = this.value;
districtSelect.innerHTML = '<option value="">请选择区县</option>';
if (selectedCity) {
cityData[selectedCity].forEach(district => {
const option = document.createElement('option');
option.value = district;
option.textContent = district;
districtSelect.appendChild(option);
});
}
});
使用Fetch API动态获取数据
从后端API异步获取级联数据

document.getElementById('category').addEventListener('change', async function() {
const categoryId = this.value;
const subcategorySelect = document.getElementById('subcategory');
subcategorySelect.innerHTML = '<option value="">加载中...</option>';
try {
const response = await fetch(`/api/subcategories?categoryId=${categoryId}`);
const subcategories = await response.json();
subcategorySelect.innerHTML = '<option value="">请选择子分类</option>';
subcategories.forEach(item => {
const option = document.createElement('option');
option.value = item.id;
option.textContent = item.name;
subcategorySelect.appendChild(option);
});
} catch (error) {
console.error('获取数据失败:', error);
subcategorySelect.innerHTML = '<option value="">加载失败</option>';
}
});
使用事件委托优化性能
对多个级联菜单使用事件委托减少事件监听器数量
document.querySelector('.cascade-container').addEventListener('change', function(event) {
if (event.target.classList.contains('level-1')) {
const selectedValue = event.target.value;
const level2Select = event.target.nextElementSibling;
// 清除现有选项
level2Select.innerHTML = '<option value="">请选择</option>';
// 根据选择加载数据
if (selectedValue) {
// 这里添加数据加载逻辑
}
}
if (event.target.classList.contains('level-2')) {
// 处理第二级选择变化
}
});
封装可复用级联组件
创建可复用的级联菜单构造函数
class CascadeMenu {
constructor(options) {
this.parentSelect = document.getElementById(options.parentId);
this.childSelect = document.getElementById(options.childId);
this.dataSource = options.dataSource;
this.init();
}
init() {
this.parentSelect.addEventListener('change', () => this.updateChildOptions());
}
async updateChildOptions() {
const parentValue = this.parentSelect.value;
this.childSelect.innerHTML = '<option value="">请选择</option>';
if (!parentValue) return;
let childData;
if (typeof this.dataSource === 'function') {
childData = await this.dataSource(parentValue);
} else {
childData = this.dataSource[parentValue] || [];
}
childData.forEach(item => {
const option = new Option(item.text, item.value);
this.childSelect.add(option);
});
}
}
// 使用示例
new CascadeMenu({
parentId: 'country',
childId: 'state',
dataSource: {
'US': [
{ value: 'CA', text: 'California' },
{ value: 'NY', text: 'New York' }
]
}
});






