当前位置:首页 > JavaScript

js实现级联菜单

2026-01-30 14:13:51JavaScript

使用纯JavaScript实现级联菜单

通过监听父级菜单的change事件动态加载子菜单数据

js实现级联菜单

// 获取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异步获取级联数据

js实现级联菜单

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' }
    ]
  }
});

标签: 菜单级联
分享给朋友:

相关文章

js实现菜单

js实现菜单

实现基本HTML结构 使用HTML创建菜单的基本框架,通常包含<ul>和<li>元素。示例结构如下: <ul id="menu"> <li><…

vue 底部菜单实现

vue 底部菜单实现

实现 Vue 底部菜单的方法 使用 v-if 或 v-show 控制显示 在 Vue 中可以通过条件渲染控制底部菜单的显示与隐藏。v-if 适合动态切换频率较低的场景,v-show 适合频繁切换的场景…

vue实现横排菜单

vue实现横排菜单

实现横排菜单的方法 在Vue中实现横排菜单可以通过多种方式完成,以下是几种常见的实现方法。 使用Flex布局实现横排菜单 通过CSS Flex布局可以轻松实现横排菜单,代码简洁且兼容性好。…

vue实现菜单权限

vue实现菜单权限

基于路由的动态菜单权限控制 在Vue中实现菜单权限通常需要结合路由配置和用户角色/权限数据。以下是常见的实现方法: 路由配置中添加权限标识 // router.js const routes =…

vue实现扇形菜单

vue实现扇形菜单

实现扇形菜单的思路 扇形菜单通常以圆形或扇形布局展示多个菜单项,可以通过CSS和Vue的动态渲染实现。关键在于计算每个菜单项的位置角度,并使用CSS的transform属性进行旋转定位。 基础HTM…

vue实现菜单递归

vue实现菜单递归

Vue 实现菜单递归的方法 在 Vue 中实现菜单递归通常需要组件调用自身,适用于多级嵌套的菜单结构。以下是几种常见的实现方式: 使用递归组件 递归组件是 Vue 中实现菜单递归的最直接方法。组件通…