• 菜单栏-JS防抖


    一、 需求

    写一个菜单栏,能够实现:

    • 鼠标悬浮时展开子菜单
    • 鼠标离开时折叠子菜单

    二、简单实现+问题

    • 简单绑定 mouseover mouseleave 实现折叠和展开。
    • 容易抽风,表现为,鼠标反复横跳几次,就会反复折叠展开

    简单实现代码:

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>防抖测试title>
        <script src="https://code.jquery.com/jquery-3.1.1.min.js">script>
        <style>
            #box, #box2{
                position: relative;
                width: 46px;
                background-color: rgb(250, 250, 250);
                padding: 5px 20px;
                text-align: center;
            }
            .row2{
                margin: 250px 0;
            }
            .menu{
                user-select: none;
            }
            .menu-list, .menu-list2{
                position: absolute;
                top: 26px;
                left: 0;
                width: 86px;
                background-color: rgb(235, 235, 235);
            }
            a{
                display: block;
                text-decoration: none;
                color: #000;
                padding: 2px 0;
            }
            a:hover{
                background-color: aliceblue;
            }
        style>
    head>
    <body>
    
        <div class="row2">
            <div id="box2">
                <div class="menu">菜单1div>
            div>
        div>
    
        <script>
            $(()=>{
                let data = [
                    {'label': "资料", 'link': '/info/123'},
                    {'label': "收藏", 'link': '/fav/123'},
                    {'label': "历史", 'link': '/history/123'},
                ]
                let listStr = ''
                for(let itm of data){
                    listStr += `${itm.link}">${itm.label}`
                }
                let listBlock2 = ``
                $('#box2').append(listBlock2)
    
                // 简单的直接绑定事件
                $("#box2,#box2").mouseover(()=>{
                    $('#box2 .menu-list2').slideDown()
                })
    
                $("#box2").mouseleave(()=>{
                    $('#box2 .menu-list2').slideUp(300)
                })
            })
        script>
        
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    效果演示:

    三、防抖

      防抖,简单解释就是将动作延迟一定时间再执行,如果在该时间内重复触发事件,那么延迟的时间会重置,只有真正达到延迟时间,才会执行回调函数。
      在这里,是将子菜单的折叠进行防抖,鼠标移开目标后,子菜单延迟一段时间折叠;若在这段时间内鼠标重新移入,那取消执行折叠,如果移入又移出,重置延迟时间,循环上述过程。
      这样就避免了鼠标不小心横跳,造成的抽风式效果。

    关键代码:

    • .menu 对应 “菜单”
    • .menu-list 对应子菜单
    let timer = ''
    $("#box .menu").mouseover(()=>{
        clearTimeout(timer)
        $('#box .menu-list').mouseover(()=>{
            clearTimeout(timer)
            $('#box .menu-list').slideDown()
        })
        $('#box .menu-list').slideDown()
    })
    
    $("#box .menu, #box .menu-list").mouseleave(()=>{
        clearTimeout(timer)
        timer = setTimeout(()=>{
            $('#box .menu-list').slideUp(300)
        }, 300)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    效果:

    四、完整代码

    • 包含简单实现和加了防抖后的部分
    • 可以直接复制到一个新的HTML文件,在浏览器打开查看效果(联网,需要加载 jquery
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>防抖测试title>
        <script src="https://code.jquery.com/jquery-3.1.1.min.js">script>
        <style>
            #box, #box2{
                position: relative;
                width: 46px;
                background-color: rgb(250, 250, 250);
                padding: 5px 20px;
                text-align: center;
            }
            .row2{
                margin: 250px 0;
            }
            .menu{
                user-select: none;
            }
            .menu-list, .menu-list2{
                position: absolute;
                top: 26px;
                left: 0;
                width: 86px;
                background-color: rgb(235, 235, 235);
            }
            a{
                display: block;
                text-decoration: none;
                color: #000;
                padding: 2px 0;
            }
            a:hover{
                background-color: aliceblue;
            }
        style>
    head>
    <body>
    
    	
        <div id="box">
            <div class="menu">菜单2div>
        div>
    
    	
        <div class="row2">
            <div id="box2">
                <div class="menu">菜单1div>
            div>
        div>
    
        <script>
            $(()=>{
            	// 填充的子菜单数据
                let data = [
                    {'label': "资料", 'link': '/info/xxx'},
                    {'label': "收藏", 'link': '/fav/xxx'},
                    {'label': "历史", 'link': '/history/xxx'},
                ]
    
                let listStr = ''
                for(let itm of data){
                    listStr += `${itm.link}">${itm.label}`
                }
                let listBlock = ``
                let listBlock2 = ``
                $('#box').append(listBlock)
                $('#box2').append(listBlock2)
    			// 防抖部分时间绑定
                let timer = ''
                $("#box .menu").mouseover(()=>{
                    clearTimeout(timer)
                    $('#box .menu-list').mouseover(()=>{
                        clearTimeout(timer)
                        $('#box .menu-list').slideDown()
                    })
                    $('#box .menu-list').slideDown()
                })
                $("#box .menu, #box .menu-list").mouseleave(()=>{
                    clearTimeout(timer)
                    timer = setTimeout(()=>{
                        $('#box .menu-list').slideUp(300)
                    }, 300)
                })
    
                // 简单的直接绑定事件
                $("#box2,#box2").mouseover(()=>{
                    $('#box2 .menu-list2').slideDown()
                })
                $("#box2").mouseleave(()=>{
                    $('#box2 .menu-list2').slideUp(300)
                })
            })
        script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
  • 相关阅读:
    一文理解Linux的基本指令(三分钟学会Linux基本指令)
    JavaScript - 将 Allegro 坐标文件转为嘉立创坐标文件(CSV 格式)的工具
    Android打包apk报错:Execution failed for task ‘:app:lintVitalRelease‘.
    如何使用正则表达式来为SpringMVC的拦截器设置拦截URI
    应用程序处理:TCP模块的处理
    Kafka系列之:实现对Kafka集群的监控
    69. x 的平方根
    Vue 模板语法 v-bind
    Office 2016、2019 解决“你的 Office 许可证有问题”
    Java企业微信对接(二)微信端回调到企业端
  • 原文地址:https://blog.csdn.net/qq_45020818/article/details/128119657