JS实现级联菜单

536 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

JS实现级联菜单

JS实现级联菜单

使用vscode快速创建html

1.在一个目录中新建html文件

点击文件夹旁文件带+的icon
在这里插入图片描述

2.填写文件名

XXX.html或者XXX.htm都可以
在这里插入图片描述

3.快速初始化html

打开创建的html文件
文件开头输入 ! 此时vscode会有提示(注意中英文,英文的!才可以)
在这里插入图片描述

出现提示时,按下 tab 键,vscode会自动生成基础的的html标签
在这里插入图片描述

设置建议下拉框

1.创建三个下拉框

使用select标签创建下拉框,select标签中增加id、name属性方便后续使用,select标签下增加option标签增加下拉框选项,第二和第三个下拉框,设置了内联样式display:none默认不显示。
在这里插入图片描述

2.预览html

点击vscode菜单栏【运行】,点击【启用调试】, 选择【chrome】,没用谷歌浏览器可以用window10的edge,或者选择更多安装其他调试环境
在这里插入图片描述
在这里插入图片描述
这是浏览器就会显示如下的网页
在这里插入图片描述

通过js对下拉框进行联动操作

1.在body标签下方添加script标签

在这里插入图片描述

2.添加变量,将数组赋值给变量

使用var关键字可以声明变量, []代表列表,列表中值使用【,】隔开,字符串使用【’】包裹,一定要注意数组的层级不然会影响后续功能
在这里插入图片描述

3.通过DOM获得网页中元素

使用document.getElementById(‘id’)方法,括号中填入前面select标签中设置的id就可以获得select元素,并将获取到的元素赋值给创建的变量
在这里插入图片描述

4.创建方法操作第二和第三个下拉框

xx.selectedIndex 下拉框选中选项的下标,从0开始
xx.removeChild()设置元素下内容,设置为空则清除内容
xx.children.length 子元素数量
var option = new Option() 创建option标签
xx.setAttribute(‘style’, “display: block;”) 设置元素的属性,直接替换原有属性
xx.appendChild()向该元素下添加子元素
doucument.createTextNode() 创建文本元素节点
在这里插入图片描述

在这里插入图片描述

5.使用for in循环遍历第一个数组,并初始化第一个select下拉框

每次循环新增一个option标签,并把数组的每个值放入option中,再把option加入到select标签下
Option() 创建option标签
xx.appendChild()给元素添加子元素
document.createTextNode()设置文本信息
在这里插入图片描述

6.通过时间监听方法初始化第二、第三个select下拉框

使用事件监听方法,当下拉框发生改变时,则调用匿名方法,匿名方法调用之前设置的方法初始化第二、第三个下拉框,同时判断如果选中的是第一个下拉框默认的选项则不发生变化
xx.addEventListener(‘mode’, function(){}) 给元素增加事件监听方法,发生对应事件则调用后续函数
在这里插入图片描述

至此我们已经实现了通过js实现级联菜单的功能,下面来实现标题的自动变化

根据下拉选择改变标题

1.新增一个变量获取标题元素

在这里插入图片描述

2.新增在原有的两个方法上添加修改标题的功能

在这里插入图片描述
在这里插入图片描述

3.新增一个方法来修改第三个下拉框选择时标题的修改

在这里插入图片描述

4.给第三个下拉框添加事件监听来改变标题

在这里插入图片描述

源码展示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=<device-width>, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 设置一个菜单标题 -->
    <p id="menuInfo">城市   ></p>
    <!-- 使用br标签换行显示 -->
    <br>
    <!-- 创建三级联动菜单并分别设置id -->
    <select name="firstMenu" id="firstMenu">
        <option>firstMenu</option>
    </select>
    <select name="seceondMenu" id="seceondMenu" style="display: none;">
        <option>seceondMenu</option>
    </select>
    <select name="thirdMenu" id="thirdMenu" style="display: none;">
        <option>thirdMenu</option>
    </select>
</body>
<script>
    // 创建变量存放数组
    var firstMenuItem = ['北京市', '天津市', '江苏省', '浙江省', '广东省', '黑龙江省']
    var seceondMenuItem = [['北京市'], ['天津市'], ['南京市', '苏州市', '无锡市'], ['杭州市', '丽水市'], ['广州市'], ['哈尔滨市']]
    var thirdMenuItem = [[['北京市']], [['天津市']], [['鼓楼区', '江宁区', '建邺区'], ['虎丘区', '吴中区'], ['惠山区']], [['萧山区', '西湖区']], [['莲都区']], [['越秀区']], [['松北区']]]
    // 通过DOM操作获取html元素
    var firstMenu = document.getElementById('firstMenu')
    var seceondMenu = document.getElementById('seceondMenu')
    var thirdMenu = document.getElementById('thirdMenu')
    // 获得标题元素
    var title = document.getElementById('menuInfo')

    // 创建方法对第二个下拉框进行操作
    function firstMenuChange(){
        // 初始化前清除除默认外所有选项
        if (seceondMenu.children.length > 1){//不清楚默认选项
            // 获取当前子节点长度(删除节点后长度会变化,会导致漏删)
            num = seceondMenu.children.length
            for (let index = 1; index < num; index++) {
                // 每次删除最有一个节点
                seceondMenu.removeChild(seceondMenu.children[seceondMenu.children.length-1])
            }
        }
        // 如果firstMenu选中的不是第一个选下则初始化seceondMenu
        if (firstMenu.selectedIndex != 0 ){
            // 获取当前标题文本信息
            nowText = '城市   >'
            // 根据第一个标题选项和原标题进行拼接格式化组成新标题文本信息
            newText = nowText + '   '+ firstMenu.children[firstMenu.selectedIndex].textContent
            // 将新标题文本信息替换原有信息
            title.textContent = newText
            // 获取第一个选项的下标,以此来从第二个多维数组中查找到对应数组
            for (const key in seceondMenuItem[firstMenu.selectedIndex - 1]) {
                var option = new Option()
                option.appendChild(document.createTextNode(seceondMenuItem[firstMenu.selectedIndex - 1][key]))
                seceondMenu.appendChild(option) 
            }
            // 将seceondMenu设置为显示
            seceondMenu.setAttribute('style', "display: block;")
        }else{
            // 选中默认选项将seceondMenu、thirdMenu设置为不显示
            seceondMenu.setAttribute('style', "display: none;")
        }
    }

    // 创建方法对第三个下拉框进行操作
    function seceondMenuChange(){
        // 初始化前清除除默认外所有选项
        if (thirdMenu.children.length > 1){
            // 获取当前子节点长度(删除节点后长度会变化,会导致漏删)
            num = thirdMenu.children.length
            for (let index = 1; index < num; index++) {
                // 每次删除最有一个节点
                thirdMenu.removeChild(thirdMenu.children[thirdMenu.children.length-1])
            }
        }
        // 如果seceondMenu选中的不是第一个选下则初始化thirdMenu
        if (seceondMenu.selectedIndex != 0 ){
            // 获取当前标题文本信息
            nowText = title.textContent
            // 根据第一个标题选项和原标题进行拼接格式化组成新标题文本信息
            newText = nowText + '   >   '+ seceondMenu.children[seceondMenu.selectedIndex].textContent
            // 将新标题文本信息替换原有信息
            title.textContent = newText
            // 获取第一个、第二个选项的下标,以此来从第三个多维数组中查找到对应数组
            for (const key in thirdMenuItem[firstMenu.selectedIndex - 1][seceondMenu.selectedIndex - 1]) {
                var option = new Option()
                option.appendChild(document.createTextNode(thirdMenuItem[firstMenu.selectedIndex - 1][seceondMenu.selectedIndex - 1][key]))
                thirdMenu.appendChild(option)
            }
            // 将seceondMenu设置为显示
            thirdMenu.setAttribute('style', "display: block;")
        }else{
            // 选中默认选项将seceondMenu、thirdMenu设置为不显示
            thirdMenu.setAttribute('style', "display: none;")
        }
    }

    // 创建方法对第三个下拉框进行操作
    function thirdMenuChage(){
        if (thirdMenuChage.selectedIndex != 0 ){
            // 获取当前标题文本信息
            nowText = title.textContent
            // 根据第一个标题选项和原标题进行拼接格式化组成新标题文本信息
            newText = nowText + '   >   '+ seceondMenu.children[seceondMenu.selectedIndex].textContent
            // 将新标题文本信息替换原有信息
            title.textContent = newText
        }
    }


    // 使用for in 循环遍历数组
    for (const key in firstMenuItem) {
        // 创建新option标签
        var option = new Option()
        // 将数组中值加入option中
        option.appendChild(document.createTextNode(firstMenuItem[key]))
        // 在firstMenu下拉框中插入option
        firstMenu.appendChild(option)
    }


    // 为firstMenu添加时间侦听,类型change,执行匿名方法,同时操作第二、第三个下拉框
    firstMenu.addEventListener('change', function(){
        firstMenuChange()
        seceondMenuChange()
    });

    
    // 为seceondMenu添加时间侦听,类型change,执行匿名方法操作第三个下拉框
    seceondMenu.addEventListener('change', function(){
        seceondMenuChange()
    })

    // 为seceondMenu添加时间侦听,类型change,执行匿名方法操作第三个下拉框
    thirdMenu.addEventListener('change', function(){
        thirdMenuChage()
    })
</script>
</html>