一般的情况下,很多组件库都包含了这个功能,但有时符合业务要求的组件并没有包含这个功能。所以有时候还是需要自己手写完成,不知道原理还是很难想到思路的,这里我就记录一下实现过程。
实现思路:主要是要想到有一个同时出现同时隐藏的遮罩层,将事件添加在遮罩层上,通过遮罩层去影响弹窗显隐。
代码中有详细的解读,可以自行复制代码参考结果。
<!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>
/* 使用visiblity来控制元素显隐,不使用display控制,浪费性能,会一直造成浏览器回流。visiblity不会出现这种情况。
但是visiblity会占据空间,display不会占据空间。看需求。
注意hidden、visible的顺序,影响优先级,visible在hidden下面。
*/
.hidden {
visibility: hidden;
}
.visible {
visibility: visible;
}
/* 遮罩层与内容区不再需要指定z-index。遮罩层与内容区平级,内容区在遮罩层的下面,z-index默认高于遮罩层。 */
.mask {
position: fixed;
/* left、right、top、bottom简写形式,同margin、padding顺序 */
inset: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.content {
width: 200px;
height: 200px;
margin: auto;
background-color: lightpink;
position: relative;
}
</style>
</head>
<body>
<div class="mask hidden"></div>
<div class="content hidden">
<div>我是第一</div>
<div>我是第二</div>
<div>我是第三</div>
<div>我是第四</div>
</div>
<button>弹窗内容展示</button>
<script>
const btn = document.querySelector('button');
const mask = document.querySelector('.mask');
const content = document.querySelector('.content');
// 当点击按钮时,通过toggle来切换类名,从而控制显隐。
btn.addEventListener('click', function () {
console.log('button');
mask.classList.toggle('visible');
content.classList.toggle('visible');
})
// 当点击遮罩层时,通过toggle来切换类名,从而控制显隐。
mask.addEventListener('click', function () {
console.log('mask');
mask.classList.toggle('visible');
content.classList.toggle('visible');
})
</script>
</body>
</html>
结果如图,点击按钮弹出遮罩层和内容。之后点击弹窗区以外可以关闭弹窗。