ClickOutSide
2021-05-09 本文已影响0人
CondorHero
ClickOutSide.png
我想我们在很多 UI 框架中都会见到过下面情景,点击指定元素之外的区域做一些事情,例如点击模版关闭 Modal。
点击模版关闭 Modal上面只是一个例子,这种用户点击指定元素之外的区域触发回调函数还有很多应用,不知道你有没有想过怎么实现的。
今天我们就来看看它的实现——ClickOutSide。
实现思路
- 整个页面即 document 文档通过 addEventListener 添加 click 事件
- 用户点击页面元素时,通过 Event.target 来获取点击的元素,然后通过 Node.contains() 和我们指定的元素进行对比,根据两个元素是否有包含关系,在决定回调函数是否触发。
基于上面的思路我们封装一个函数 onClickOutSide:
const onClickOutside = (element, callback) => {
document.addEventListener("click", e => {
if (!element.contains(e.target)) callback();
});
};
我们来应用下,写个 demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hi onClickOutside!</title>
<style>
* {margin: 0; padding: 0;}
html {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
div {
line-height: 200px;
height: 200px;
width: 200px;
text-align: center;
border: 1px dashed orange;
}
</style>
</head>
<body>
<div id="div-DOM"></div>
<script>
const onClickOutside = (element, callback) => {
document.addEventListener("click", e => {
const isClickOutSide = !element.contains(e.target);
element.textContent = isClickOutSide ? "外部" : "内部";
if (isClickOutSide) callback();
});
};
const divDOM = document.getElementById("div-DOM");
onClickOutside(divDOM , () => { alert("hi onClickOutside!")});
</script>
</body>
</html>
可以看到点击指定元素外部区域触发了回调函数,点击指定元素,回调函数没有触发:
2021-05-09 16-51-19.2021-05-09 16_51_55.gif除了给 click 事件,我们还可以发挥想象给 mouseover 事件,更大可能由你发挥。
应用到 React
接下来我们看看如何应用到 React 中去。
import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
const useClickOutside = (ref, callback) => {
const handleClick = e => {
if (ref.current && !ref.current.contains(e.target)) {
callback();
}
};
React.useEffect(() => {
document.addEventListener('click', handleClick);
return () => {
document.removeEventListener('click', handleClick);
};
});
};
const ClickBox = ({ onClickOutside }) => {
const clickRef = React.useRef();
useClickOutside(clickRef, onClickOutside);
return (
<div className="click-box" ref={clickRef} style={{
border: '2px dashed orangered',
height: 200,
width: 400,
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
}}>
<p>Click out of this element</p>
</div>
);
};
ReactDOM.render(
<>
<ClickBox onClickOutside={() => alert('click outside')} />
</>,
document.getElementById('container'),
);
渲染到页面上:
Click out of this element应用到 Vue
可以参考着 React 的写。
最后
今天母亲节,恭祝天下的妈妈,平安健康快乐!
当前时间 Sunday, May 9, 2021 20:08:08