在前端开发中,我们大量使用开源很多UI框架和js框架,让我们使用的越好,做项目越快,但是同时让我们也对最基本的css属性和js最基本和最底层的api都遗忘,所以我们通过自己封装插件和组件,让我们更容易拾起最基本的知识点;以下我会从3个部分总结这个过程:1.原生js和jquery实现基本弹框效果,2.使用面向对象js和jquery常用封装方法,3.通过vue封装和优化弹窗组件
- 通过js和jquery实现弹窗效果
静态节点实现(有弊端哟)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>原生Popup弹出层</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
overflow: hidden;
}
.mask {
width: 100%;
height: 100vh;
background-color: black;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
opacity: 0;
visibility: hidden;
transition: all .3s linear;
}
.view {
width: 100%;
height: 0;
background-color: #fff;
position: absolute;
left: 0;
bottom: 0;
z-index: 1000;
display: block;
transition: all .3s linear;
}
.show {
opacity: .6;
visibility: visible;
}
.show2 {
height: 12.5rem;
}
</style>
</head>
<body>
<!-- 不要使用 display 会影响过渡动画呦!!! -->
<div>
<button id="btn">test</button>
<div>fsdfasd</div>
</div>
<div class="popup">
<!-- 遮罩层 -->
<div class="mask"></div>
<!-- 显示层 -->
<div class="view">
显示东西
</div>
</div>
</body>
<script>
//原生js版
var popup = document.getElementsByClassName("popup")[0];
var btn = document.getElementById("btn");
var mask = document.getElementsByClassName("mask")[0];
var view = document.querySelector(".view");
btn.addEventListener('click', function() {
mask.classList.add("show");
view.classList.add("show2");
}, false)
popup.addEventListener('click', function(e) {
console.log(e.currentTarget)// 事件绑定的元素
console.log(e.target);//用户点击的真实元素
mask.classList.remove("show");
view.classList.remove("show2");
// if(e.target.className == "")
}, false)
// jquery版
$(function() {
console.log($);
$("#btn").click(() => {
$(".mask").addClass("show");
$(".view").addClass("show2");
})
$(".popup").click(() => {
$(".mask").removeClass("show");
$(".view").removeClass("show2");
})
})
</script>
</html>
bug:
- 该类名
.popup
元素一直存在与dom中。我们要达到效果,用户点击时,插入弹出层的节点,关闭时,销毁弹出层的节点,所以我们要动态的插入和销毁.popup
节点
js动态节点实现弹框(优化静态节点实现)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>原生Popup弹出层</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
overflow: hidden;
}
.mask {
width: 100%;
height: 100vh;
background-color: black;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
opacity: 0;
visibility: hidden;
transition: all 1s linear;
}
.view {
width: 100%;
height: 0;
background-color: #fff;
position: absolute;
left: 0;
bottom: 0;
z-index: 1000;
display: block;
transition: all 1s linear;
}
.show {
opacity: .6;
visibility: visible;
}
.show2 {
height: 12.5rem;
}
</style>
</head>
<body>
<!-- 不要使用 display 会影响过渡动画呦!!! -->
<div>
<button id="btn">test</button>
<div class="page">fsdfasd</div>
</div>
</body>
<script>
window.onload = function() {
// 获取操作的dom对象
var oTest = document.getElementById("btn");
var oMask = null;
var oView = null;
function createPopup() {
//获取参数信息
// var sHeight = document.documentElement.scrollHeight;
// var sWidth = document.documentElement.scrollWidth;
// 我们这里可以使用 字符串转node节点对象,来创建弹出层的dom结构,方便简洁
var strHtml = `
<div class="popup">
<div class="mask"></div>
<div class="view">
显示内容
</div>
</div>
`
//生成节点
var popupDom = new DOMParser().parseFromString(strHtml,'text/html').body.childNodes[0];
document.body.appendChild(popupDom);
}
function destoryPopup() {
var popupNode = document.body.querySelectorAll(".popup");
if(popupNode.length <= 0) return;
Array.prototype.forEach.call(popupNode, (node) => {
document.body.removeChild(node);
})
}
oTest.addEventListener('click', function() {
createPopup();
// 注意: 添加过渡动画时,要放入宏观任务队列
setTimeout(() => {
//添加过渡类名
oMask = document.documentElement.querySelector(".mask");
oView = document.documentElement.querySelector(".view");
oMask.classList.add("show");
oView.classList.add("show2");
})
}, false)
document.body.addEventListener('click', function(e) {
if(e.target.classList.contains("mask")) {
oMask.classList.remove("show");
oView.classList.remove("show2");
setTimeout(() => {
destoryPopup();
}, 1000);// 这个时间和你过渡动画时间一致
}
}, false)
}
/* 1. 咋样给动态的dom节点添加过渡动画呢?
为什么没有动画?
在js单线程执行,尤其在同步任务中,所有的执行逻辑都是同步进行,也就是说 创建遮罩层和添加show类名是同时的,所以导致没有效果
我们要把添加过渡最后类名,添加到异步队列中执行。setTimeout()
*/
</script>
</html>
注意:
动态的dom节点添加过渡动画呢一定要注意js单线程执行同步任务,但是我们的过渡动画是有时间段的,也就是两种状态的。在js单线程执行,尤其在同步任务中,所有的执行逻辑都是同步进行,也就是说 创建遮罩层和添加show类名是同时的,所以导致m没有效果我们要把添加过渡最后类名,添加到异步队列中执行。setTimeout()实现宏观任务队列
jquery动态节点实现弹框
$(function() {
function createPopup() {
var template = `
<div class="popup">
<div class="mask"></div>
<div class="view">
显示内容
</div>
</div>
`
//jquery append方法加强了可以传入字符串;原生js只能传node对象
$("body").append(template);
}
function destoryPopup() {
if($(".popup").length <= 0) return;
$(".popup").remove();
}
// destoryPopup()
$("#btn").click(() => {
createPopup();
setTimeout(() => {
$(".mask").addClass("show");
$(".view").addClass("show2");
});
})
$("body").on("click",(e) => {
if(e.target.classList.contains("mask")) {
$(".mask").removeClass("show");
$(".view").removeClass("show2");
setTimeout(() => {
destoryPopup();
}, 1000);// 这个时间和你过渡动画时间一致
}
})
})
网友评论