点击元素以外的事件监听

news/2024/7/17 3:52:52

在项目中,我们经常会遇到需要监听目标元素以外的区域被点击或鼠标移入移出等需求。

例如下面我们有一个表格里面嵌套表单的组件
默认展示

我希望点击n行的时候,n行的元素变成表单元素进行输入或者选择,
点击该行

当我点击其他其他区域n行又会恢复成数据展示的样子。
默认展示
那现在我们来想想这种监听应该如何实现呢?

contains

如果你听说过 contains这个方法,那么你会豁然开朗。这个方法的作用是用来判断一个元素是否包含另一个元素。那么如果我们通过事件对象拿到当前事件的目标元素,再通过 contains去判断这个目标元素有没有在我们需要监听的元素内部,就可以轻易实现我们的需求了。

上代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>body {margin: 0;padding: 0;background-color: aqua;width: 100vw;height: 100vh;}.parent {width: 100px;height: 100px;background-color: yellow;}.son {position: relative;left: 30px;top: 30px;width: 30px;height: 30px;background-color: red;}</style>
</head><body><div class="parent"><div class="son"></div></div><script>const parentEle = document.querySelector('.parent')document.body.addEventListener('click', e => {const target = e.targetif (parentEle.contains(target)) {alert('点击了元素包含区域')} else {alert('点击了元素以外区域')}})</script>
</body></html>

也附上一个可以直接预览效果的地址

当然,我们可以做到更加便捷。如果是在vue项目里我们可以创建一个自定义指令的方式便捷实现监听效果。

export default function install(Vue) {Vue.directive('clickoutside', {bind(el, { value: fun, arg }) {console.log(arg)arg = arg || 'click'document.addEventListener(arg, handleFun.bind(null, el, fun))},unbind() {document.removeEventListener(arg, handleFun)},})
}function handleFun(el, fun, e) {let flag = el.contains(e.target)if (!flag) {fun()}
}
<button v-clickoutside="fn">按钮</button>

上面是一个极其简单的自定义指令,默认监听点击事件,它可以用来监测点击的元素是否在我们所监测的元素内。不在则执行指令绑定的方法。

最后再补充一个,如果你使用了element-ui,那么他的内部其实是自带了这样一个方法的。
你可以像这样进行引用

import clickoutside from 'element-ui/src/utils/clickoutside'

https://www.xjx100.cn/news/3119004.html

相关文章

nvm for windows使用与node/npm/yarn的配置

1 下载 nvm for windows download – github 下拉到Assets, 下载.exe文件 2 安装 安装到如下文件夹中 目录可以自己选, 可以换别的名字, 自己记住即可 新手建议全部看完再进行个人配置, 或者使用与博主一致的路径 D:\DevelopEnvironment\nvm3 配置nvm使用的镜像 node_mir…

Opencv手势控制音量!附源码!

效果演示&#xff1a; 废话不多说&#xff01;直接上源码&#xff01;下面写有所有代码注释&#xff01;&#xff01; import cv2 import mediapipe as mp #它包含了各种预训练的机器学习模型&#xff0c;可以用于姿势估计、手势识别等任务 from ctypes import cast, POINTE…

(C++)移动零--双指针法

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://le…

HTTP /1.0 /1.1 /2.0 /3.0改变和区别

HTTP&#xff08;Hypertext Transfer Protocol&#xff09;是一种用于传输超文本的协议&#xff0c;它是Web上数据通信的基础。不同版本的HTTP协议有一些重要的变化和改进。以下是HTTP/1.0、HTTP/1.1、HTTP/2.0和HTTP/3.0的主要变化和区别&#xff1a; HTTP/1.0: 1.无连接性&…

根据Java的数据库实体类输出建表SQL

数据库实体类 import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode;/*** 分子公司基本信息变更代办** version 1.0* date 2023/11/21 01:01*/ EqualsAndHashCode(callSuper true) Data TableName("ent_change_t…

【Axure高保真原型】区间评分条

今天和大家分享区间评分条的原型模板&#xff0c;我们可以左右拖动移动滑块到指定位置&#xff0c;评分条上方会根据两个滑块所在的位置&#xff0c;自动计算出对应的区间范围&#xff1b;这个原型模板使用也很简单&#xff0c;只需要在里面填写区间的最大值&#xff0c;即可自…

前端如何中断请求 ( axios、原生 ajax、fetch)

使用场景 在前端开发中&#xff0c;我们经常需要中断请求来优化性能或处理特定的业务需求。以下是一些常见的使用场景&#xff1a; 比如 重复请求&#xff1a;当页面中多个组件并发调用同一个接口时&#xff0c;在第一个请求返回后&#xff0c;我们可能需要中断其他组件对该接…

ARM预取侧信道(Prefetcher Side Channels)攻击与防御

目录 一、预取侧信道简介 1.1 背景:预取分类 二、Arm核会受到影响吗? 2.1 先进的预取器