具体效果演示
实现代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
<title>点击相关按钮出现相关的div,div出现后点击除div外的其它地方隐藏相关的div</title>
<!--引入 element-ui 的样式,-->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 必须先引入vue,后使用element-ui -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<!-- 引入element 的组件库-->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<style>
#operate {
position: relative;
}
#operate div {
width: 8%;
border: 1px solid gainsboro;
position: absolute;
top: 35px;
padding: 10px;
z-index: 1;
}
#operate div .el-button {
width: 100%;
text-align: left;
}
#operate div .el-button:first-of-type {
margin-bottom: 5px;
}
</style>
</head>
<body>
<div id="app">
<el-row id="operate" type="flex" justify="center">
<el-button type="warning" size="mini" @click="clickBtn">操作</el-button>
<div v-show="operateBtn" id="setOperate">
<el-button type="primary" size="mini">编辑信息</el-button><br>
<el-button type="primary" size="mini">修改密码</el-button>
</div>
</el-row>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
// 控制相关的下拉菜单是否进行显示
operateBtn: false,
}
},
methods: {
// 当点击操作后所执行的事件
clickBtn(e) {
// 阻止事件冒泡(此时绑定了全局点击事件,以防全局点击事件与操作按钮点击事件相互冲突)
e.stopPropagation()
this.operateBtn = !this.operateBtn
// 当相关页面渲染完成后绑定全局点击事件(全局绑定事件中需要获取相关的dom元素,故需要等页面渲染完成后进行相关的操作)
this.$nextTick(() => {
document.addEventListener('click', this.setClick)
})
},
setClick(e) {
let oDiv = document.getElementById("setOperate")
// 获取到div中四个顶点的相关x和y坐标值
let x1 = oDiv.getBoundingClientRect().left
let x2 = oDiv.getBoundingClientRect().left + oDiv.getBoundingClientRect().width
let y1 = oDiv.getBoundingClientRect().top
let y2 = oDiv.getBoundingClientRect().top + oDiv.getBoundingClientRect().height
// 获取到鼠标点击的相关坐标位置
let x = e.clientX
let y = e.clientY
// 当鼠标点击到div之外时隐藏div,同时解除绑定的全局鼠标点击事件
if(x < x1 || x > x2 || y < y1 || y > y2) {
this.operateBtn = false
document.removeEventListener('click', this.setClick)
}
}
}
})
</script>
</body>
</html>
如果有更好的实现方法,欢迎进行交流哦。