js实现三级级联
实现三级级联的基本思路
三级级联通常指三个下拉菜单之间的联动选择,例如省、市、区三级联动。核心逻辑是通过前一级的选择动态加载下一级的数据。
数据结构准备
使用嵌套对象或数组存储级联数据。例如:
const data = {
'广东省': {
'广州市': ['天河区', '越秀区', '海珠区'],
'深圳市': ['福田区', '南山区', '罗湖区']
},
'江苏省': {
'南京市': ['玄武区', '秦淮区', '建邺区'],
'苏州市': ['姑苏区', '虎丘区', '吴中区']
}
};
HTML结构
创建三个select元素并设置id:
<select id="province">
<option value="">请选择省份</option>
</select>
<select id="city">
<option value="">请选择城市</option>
</select>
<select id="district">
<option value="">请选择区县</option>
</select>
初始化省份数据
页面加载时填充第一级选项:
const provinceSelect = document.getElementById('province');
Object.keys(data).forEach(province => {
const option = document.createElement('option');
option.value = province;
option.textContent = province;
provinceSelect.appendChild(option);
});
城市级联逻辑
监听省份变化事件,动态加载城市数据:
provinceSelect.addEventListener('change', function() {
const citySelect = document.getElementById('city');
citySelect.innerHTML = '<option value="">请选择城市</option>';
const districtSelect = document.getElementById('district');
districtSelect.innerHTML = '<option value="">请选择区县</option>';
if (this.value) {
Object.keys(data[this.value]).forEach(city => {
const option = document.createElement('option');
option.value = city;
option.textContent = city;
citySelect.appendChild(option);
});
}
});
区县级联逻辑
监听城市变化事件,动态加载区县数据:
document.getElementById('city').addEventListener('change', function() {
const districtSelect = document.getElementById('district');
districtSelect.innerHTML = '<option value="">请选择区县</option>';
const province = document.getElementById('province').value;
if (province && this.value) {
data[province][this.value].forEach(district => {
const option = document.createElement('option');
option.value = district;
option.textContent = district;
districtSelect.appendChild(option);
});
}
});
完整代码示例
将所有部分组合:
document.addEventListener('DOMContentLoaded', function() {
const data = {
'广东省': {
'广州市': ['天河区', '越秀区', '海珠区'],
'深圳市': ['福田区', '南山区', '罗湖区']
},
'江苏省': {
'南京市': ['玄武区', '秦淮区', '建邺区'],
'苏州市': ['姑苏区', '虎丘区', '吴中区']
}
};
const provinceSelect = document.getElementById('province');
Object.keys(data).forEach(province => {
const option = document.createElement('option');
option.value = province;
option.textContent = province;
provinceSelect.appendChild(option);
});
provinceSelect.addEventListener('change', function() {
const citySelect = document.getElementById('city');
citySelect.innerHTML = '<option value="">请选择城市</option>';
const districtSelect = document.getElementById('district');
districtSelect.innerHTML = '<option value="">请选择区县</option>';
if (this.value) {
Object.keys(data[this.value]).forEach(city => {
const option = document.createElement('option');
option.value = city;
option.textContent = city;
citySelect.appendChild(option);
});
}
});
document.getElementById('city').addEventListener('change', function() {
const districtSelect = document.getElementById('district');
districtSelect.innerHTML = '<option value="">请选择区县</option>';
const province = document.getElementById('province').value;
if (province && this.value) {
data[province][this.value].forEach(district => {
const option = document.createElement('option');
option.value = district;
option.textContent = district;
districtSelect.appendChild(option);
});
}
});
});
使用AJAX动态加载数据
对于大数据量场景,建议从后端API获取数据:
// 获取省份
fetch('/api/provinces')
.then(response => response.json())
.then(provinces => {
// 填充省份select
});
// 城市选择事件
provinceSelect.addEventListener('change', function() {
fetch(`/api/cities?province=${this.value}`)
.then(response => response.json())
.then(cities => {
// 填充城市select
});
});
注意事项
- 添加默认空选项提升用户体验
- 清除下级选项时保留默认选项
- 考虑添加加载状态提示
- 对异步操作进行错误处理
- 移动端需考虑触摸事件兼容性
性能优化建议
- 使用文档片段减少DOM操作
- 对频繁操作进行防抖处理
- 考虑前端缓存已加载的数据
- 大数据量时使用虚拟滚动技术







