一、 需求
写一个菜单栏,能够实现:
- 鼠标悬浮时展开子菜单
- 鼠标离开时折叠子菜单
二、简单实现+问题
- 简单绑定
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">菜单1</div>
</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 += `<a href="${itm.link}">${itm.label}</a>`
}
let listBlock2 = `<div hidden class="menu-list2">${listStr}</div>`
$('#box2').append(listBlock2)
// 简单的直接绑定事件
$("#box2,#box2").mouseover(()=>{
$('#box2 .menu-list2').slideDown()
})
$("#box2").mouseleave(()=>{
$('#box2 .menu-list2').slideUp(300)
})
})
</script>
</body>
</html>
效果演示:
三、防抖
防抖,简单解释就是将动作延迟一定时间再执行,如果在该时间内重复触发事件,那么延迟的时间会重置,只有真正达到延迟时间,才会执行回调函数。
在这里,是将子菜单的折叠进行防抖,鼠标移开目标后,子菜单延迟一段时间折叠;若在这段时间内鼠标重新移入,那取消执行折叠,如果移入又移出,重置延迟时间,循环上述过程。
这样就避免了鼠标不小心横跳,造成的抽风式效果。
关键代码:
.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)
})
效果:
四、完整代码
- 包含简单实现和加了防抖后的部分
- 可以直接复制到一个新的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">菜单2</div>
</div>
<!-- 简单实现部分 -->
<div class="row2">
<div id="box2">
<div class="menu">菜单1</div>
</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 += `<a href="${itm.link}">${itm.label}</a>`
}
let listBlock = `<div hidden class="menu-list">${listStr}</div>`
let listBlock2 = `<div hidden class="menu-list2">${listStr}</div>`
$('#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>
标签:box,防抖,menu,list,timer,菜单栏,let,JS,box2
From: https://www.cnblogs.com/pxoxq/p/16991935.html