点击空白区域隐藏此模块
因为今天公司做项目的时候用到了,也百度看了一些资料,总结一下简单的写法吧,基于vue框架写的这个东西,以下拉菜单组件为例子,我自己总结了一下
首先要明了想要操作的目标元素和触发事件
触发显示的目标元素:你要对于通过哪个元素来触发事件
想要显示或者隐藏的目标元素:通过点击不同的区域显示还是隐藏的元素
触发的监听事件:既然是点击肯定是click,或者是鼠标的按下和松开mousedown等等,这个例子我们用click
<template>
<div>
<div>
<div class="drop">
<div class="outer">{{ index }}</div>
<ion-icon
ref="ico"
class="iions"
name="caret-down-sharp"
></ion-icon>
<div>
<div class="inner" v-show="show">
<ul>
<li
v-for="(item, index) in datas"
:key="index"
@click="pitch(item)"
>
{{ item }}
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "DateSelector",
data() {
return {
name: "",
show: true,
datas: [2020, 2021, 2022],
index: "",
};
},
computed: {},
mounted() {
document.addEventListener("click", this.select);
},
methods: {
select($event) {
this.show = true;
let sp = this.$refs.ico;
if (sp) {
if (!sp.contains($event.target)) {
//这句是说如果我们点击到了id为myPanel以外的区域
this.show = false;
}
}
},
pitch(item) {
this.index = item;
},
},
watch: {},
};
</script>
<style scoped>
.selectdate {
display: flex;
height: 20px;
line-height: 20px;
margin-top: 5px;
margin-bottom: 5px;
}
.drop {
position: relative;
display: flex;
width: 80px;
line-height: 20px;
border-bottom: 1px solid rgba(0, 0, 0, 0.5);
}
.outer {
width: 56px;
height: 20px;
text-align: center;
line-height: 20px;
}
.iions {
font-size: 15px;
margin-top: 2px;
cursor: pointer;
}
ul {
width: 80px;
padding: 0;
margin: 0;
list-style: none;
}
li {
height: 20px;
background: #fff;
text-align: center;
padding: 0;
margin: 0;
list-style: none;
border-bottom: 1px solid rgba(0, 0, 0, 0.3);
cursor: pointer;
line-height: 25px;
}
.inner {
position: absolute;
top: 25px;
left: 0px;
z-index: 1000;
}
.qi {
display: inline-block;
width: 40px;
text-align: center;
}
</style>
简单写了一个小组件作为样例做示范
需求分析:因为做下拉框时候,点击其他空白区域使得下拉框关闭,下拉框通过👇按钮触发也就是触发显示的目标元素,下拉列表通过v-show=”show“控制隐藏还是显示下拉的列表也就是想要显示或者隐藏的目标元素
(1)需要判断点击的是👇按钮还是👇按钮之外的区域,如果是按钮则直接使得show=true,如果是区域外的地方则show=false
但是怎么判断是否为区域外还是区域内呢?
我们直接做一个监听即可,监听整个click事件,也就是我们说的触发的监听事件,那么我们三元素已经凑齐了,
第一步,我们对于点击事件做一个全局的监听(无论在哪里点击都可以响应)
mounted() {
document.addEventListener("click", this.select);
},
每次点击时候都会触发this.select这个方法,这个方法也就是下边的方法
select($event) {
let sp = this.$refs.ico;
if (sp) {
if (!sp.contains($event.target)) {
//这句是说如果我们点击到了触发显示的目标元素以外的区域
this.show = false;
}else{
this.show = true;
}
}
},
触发之后我们传入一个$event是指当前触发的是什么事件(鼠标事件,键盘事件等)而后续我们也会用到 $event.target则指的是事件触发的目标,即哪一个元素触发了事件,这将直接获取该dom元素,直接在这里解释了
继续,我们这里通过$refs直接得到触发显示的目标元素,(vue框架知识,不像用document特别繁琐,这里vue独特的方式非常方便不多说)
(1)判断该元素是否存在
(2)判断是否点击到了触发显示的目标元素以外的区域,如果是直接显示fasle,否则显示出来即可
!sp.contains( $event.target)
简单就说这么多,用到了觉得不错,总结下来,还是那句话,积少成多,终成大器!