多级联动下拉菜单是指一组相互关联的下拉选择框,后一级菜单的选项内容会根据前一级菜单的选择动态变化。这种交互模式常见于地区选择、分类选择等场景。
<!DOCTYPE html>
<html>
<head>
<title>多级联动下拉菜单</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<select id="province">
<option value="">请选择省份</option>
<option value="gd">广东省</option>
<option value="zj">浙江省</option>
</select>
<select id="city">
<option value="">请选择城市</option>
</select>
<select id="district">
<option value="">请选择区县</option>
</select>
<script>
$(document).ready(function() {
// 省份数据
const provinceData = {
gd: ['广州', '深圳', '珠海'],
zj: ['杭州', '宁波', '温州']
};
// 城市数据
const cityData = {
'广州': ['天河区', '越秀区', '海珠区'],
'深圳': ['福田区', '南山区', '罗湖区'],
'珠海': ['香洲区', '斗门区', '金湾区'],
'杭州': ['上城区', '下城区', '西湖区'],
'宁波': ['海曙区', '江北区', '鄞州区'],
'温州': ['鹿城区', '龙湾区', '瓯海区']
};
// 省份选择变化时
$('#province').change(function() {
const provinceVal = $(this).val();
const $citySelect = $('#city');
$citySelect.empty().append('<option value="">请选择城市</option>');
$('#district').empty().append('<option value="">请选择区县</option>');
if (provinceVal) {
const cities = provinceData[provinceVal];
cities.forEach(function(city) {
$citySelect.append(`<option value="${city}">${city}</option>`);
});
}
});
// 城市选择变化时
$('#city').change(function() {
const cityVal = $(this).val();
const $districtSelect = $('#district');
$districtSelect.empty().append('<option value="">请选择区县</option>');
if (cityVal) {
const districts = cityData[cityVal];
districts.forEach(function(district) {
$districtSelect.append(`<option value="${district}">${district}</option>`);
});
}
});
});
</script>
</body>
</html>
// 通用多级联动函数
function createCascadeSelect(selectors, dataSource) {
// 为每个下拉框绑定change事件
selectors.forEach((selector, index) => {
if (index < selectors.length - 1) {
$(selector).on('change', function() {
const value = $(this).val();
const nextSelector = selectors[index + 1];
// 清空后续所有下拉框
for (let i = index + 1; i < selectors.length; i++) {
$(selectors[i]).empty().append('<option value="">请选择</option>');
}
// 如果有值,填充下一级选项
if (value) {
const nextOptions = dataSource(value);
nextOptions.forEach(option => {
$(nextSelector).append(`<option value="${option.value}">${option.text}</option>`);
});
}
});
}
});
}
// 使用示例
$(document).ready(function() {
createCascadeSelect(['#level1', '#level2', '#level3'], function(currentValue) {
// 根据当前值返回下一级选项
if (!currentValue) return [];
// 模拟数据源
const data = {
'fruit': [
{value: 'apple', text: '苹果'},
{value: 'banana', text: '香蕉'}
],
'vegetable': [
{value: 'tomato', text: '番茄'},
{value: 'potato', text: '土豆'}
],
'apple': [
{value: 'red', text: '红苹果'},
{value: 'green', text: '青苹果'}
],
'banana': [
{value: 'big', text: '大香蕉'},
{value: 'small', text: '小香蕉'}
]
};
return data[currentValue] || [];
});
});
原因:
解决方案:
$(document).ready()
中执行代码原因:
解决方案:
document.createDocumentFragment()
批量添加选项// 优化大量选项添加
function addOptionsOptimized(selector, options) {
const fragment = document.createDocumentFragment();
options.forEach(option => {
const opt = document.createElement('option');
opt.value = option.value;
opt.textContent = option.text;
fragment.appendChild(opt);
});
$(selector).append(fragment);
}
原因:
解决方案:
// 异步数据加载示例
$('#mainCategory').change(async function() {
const categoryId = $(this).val();
$('#subCategory').empty().append('<option value="">加载中...</option>');
try {
const subCategories = await fetchSubCategories(categoryId);
$('#subCategory').empty().append('<option value="">请选择子分类</option>');
subCategories.forEach(cat => {
$('#subCategory').append(`<option value="${cat.id}">${cat.name}</option>`);
});
} catch (error) {
$('#subCategory').empty().append('<option value="">加载失败</option>');
}
});
async function fetchSubCategories(categoryId) {
// 模拟API请求
return new Promise(resolve => {
setTimeout(() => {
resolve([
{id: 1, name: '子分类1'},
{id: 2, name: '子分类2'}
]);
}, 500);
});
}
// 配置驱动的多级联动
function configurableCascade(config) {
config.selectors.forEach((selector, index) => {
if (index < config.selectors.length - 1) {
$(selector).on('change', function() {
const value = $(this).val();
const nextSelector = config.selectors[index + 1];
// 清空后续所有下拉框
for (let i = index + 1; i < config.selectors.length; i++) {
$(config.selectors[i]).empty().append(`<option value="">${config.placeholder || '请选择'}</option>`);
}
if (value) {
config.dataLoader(value, function(nextOptions) {
nextOptions.forEach(option => {
$(nextSelector).append(`<option value="${option.value}">${option.text}</option>`);
});
// 如果有初始值,设置下一级的值
if (config.initialValues && config.initialValues[index + 1]) {
$(nextSelector).val(config.initialValues[index + 1]).trigger('change');
}
});
}
});
}
});
// 设置初始值
if (config.initialValues && config.initialValues[0]) {
$(config.selectors[0]).val(config.initialValues[0]).trigger('change');
}
}
// 使用示例
configurableCascade({
selectors: ['#country', '#state', '#city'],
placeholder: '请选择',
initialValues: ['us', 'ca', 'la'], // 可选
dataLoader: function(currentValue, callback) {
// 模拟异步数据加载
setTimeout(() => {
const data = {
'us': [{value: 'ny', text: '纽约'}, {value: 'ca', text: '加利福尼亚'}],
'ca': [{value: 'la', text: '洛杉矶'}, {value: 'sf', text: '旧金山'}],
'ny': [{value: 'nyc', text: '纽约市'}, {value: 'alb', text: '奥尔巴尼'}]
};
callback(data[currentValue] || []);
}, 300);
}
});
<!-- 引入Select2插件 -->
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script>
$(document).ready(function() {
// 初始化带搜索的下拉框
$('.searchable-select').select2();
// 多级联动逻辑
$('#category').change(function() {
const categoryId = $(this).val();
$('#subcategory').empty().trigger('change');
if (categoryId) {
// 模拟异步加载
setTimeout(() => {
const options = [
{id: 'sub1', text: '子分类1'},
{id: 'sub2', text: '子分类2'}
];
options.forEach(opt => {
$('#subcategory').append(new Option(opt.text, opt.id));
});
$('#subcategory').trigger('change');
}, 500);
}
});
});
</script>
<select id="category" class="searchable-select">
<option value="">请选择分类</option>
<option value="1">电子产品</option>
<option value="2">家居用品</option>
</select>
<select id="subcategory" class="searchable-select">
<option value="">请先选择分类</option>
</select>
通过以上方法和示例,您可以实现各种复杂度的多级联动下拉菜单,并根据实际需求进行调整和扩展。
没有搜到相关的文章