前言
相信很多项目中都会有这样一个小需求(PC端,移动端则是点击),鼠标移上某个菜单或者某个位置,显示一个弹出框,移开则隐藏弹出框,就是css中hover效果,这种通常做法是每个子菜单下都有一个弹框,父元素相对定位,子元素绝对定位,只需要控制的弹框的显示与隐藏即可,但是,当鼠标移动到边界的菜单上时,弹框可能会超出外部元素的范围
,如下图:
解决办法
动态的计算弹框距离外部元素的位置,即获取元素的offsetLeft、offsetTop、offsetWidth、offsetHeight,如果弹框的宽度(offsetWidth)+距离左边的距离(offsetLeft)大于父元素的宽度,则判断为超出外部元素范围,需要动态改变弹框距离边框的位置
下面是对offsetTop,offsetHeight,clientHeight,scrollHeight,scrollTop图解
注意,这里对弹框的布局有限制,虽然弹框要隐藏,但是不能使用display:none
的方式隐藏,可以使用opacity:0
或者visibility: hidden
隐藏元素,因为display:none
方式不能获取到元素的高度,宽度等
下面是我写的一个demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
#box {
width: 500px;
height: 500px;
background: #0a67fb;
margin: 100px auto;
position: relative;
}
#inner-box {
width: 200px;
height: 200px;
background: #00F7DE;
position: absolute;
top: 50px;
left: 320px;
visibility: hidden;
}
</style>
<body>
<div id="box">
<div id="inner-box">
</div>
</div>
<script>
var box = document.querySelector('#box');
var innerbox = document.querySelector('#inner-box');
box.onmouseenter = function (e) {
var wrapperBoxWidth = box.offsetWidth;// 获取父容器宽度
var wrapperBoxHeight = box.offsetHeight;// 获取父容器高度
var innerBoxWidth = innerbox.offsetWidth;// 获取弹框宽度
var innerBoxHeight = innerbox.offsetHeight;// 获取弹框高度
var innerBoxLeft = innerbox.offsetLeft;// 获取弹框距离左侧宽度
var innerBoxTop = innerbox.offsetTop;// 获取弹框距离顶部高度
innerbox.style.visibility = 'visible' // 鼠标移入时显示弹框
// 如果弹框宽度+距离左侧宽度大于外部元素的宽度,则右侧溢出
if (innerBoxLeft + innerBoxWidth > wrapperBoxWidth) {
innerbox.style.left = 'auto'
innerbox.style.right = '10px'
}
// 如果弹框高度+距离顶部高度大于外部元素的高度,则底部溢出
if (innerBoxTop + innerBoxHeight > wrapperBoxHeight) {
innerbox.style.top = 'auto'
innerbox.style.bottom = '10px'
}
}
box.onmouseleave = function () {
innerbox.style.visibility = 'hidden' // 鼠标移开时隐藏弹框
}
</script>
</body>
</html>
以上代码亲测可以解决弹框溢出问题,如果道友有更好的解决办法,欢迎指出,不胜感激!!!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。