以前觉得自己手写一个类似layui的弹出层是挺遥远的事,因为完全没有头绪,即便在layui官网知道layui使用的都是C3动画
之前试过控制width:0;height:0来做动画,结果惨不忍睹,直到几天前灵机一动联想到了tranform的scale属性,才稍微触及到了皮毛
为了不添加格外的HTML结构,所以弹出层也是动态生成
layui弹出框和遮罩层是同级结构,而我把弹出框放遮罩层里了,所以关闭时要用animationend来监听,弹出框做完动画后才删除遮罩层
确认框confirm之前也想跟原生confirm一样,通过返回布尔值来进行流程控制,结果为undefined,因为在调用时就已经返回了,而不是点了“确定“”才有返回值,这里和原生的一样,所以跟layui一样使用callback
HTML
<input type="button" value="模拟layui弹出层" id="btn-alert">
JS
function MsgAlert() {
this.alert = function (msg, time) {
var delay = time || 1200,
that = this;
$('body').append('<div id="msgAlertMask">\n' +
' <div id="msgAlert">\n' +
' <div class="title">\n' +
' <span class="close">×</span>\n' +
' </div>\n' +
' <div class="content">' + msg + '</div>\n' +
' </div>\n' +
'</div>');
$('#msgAlert').addClass('alert-show');
$('#msgAlert').on('click', '.close', function () {
that.destroy();
});
setTimeout(function () {
that.destroy();
}, delay);
};
this.confirm = function (msg, callback) {
var that = this;
$('body').append('<div id="msgAlertMask">\n' +
' <div id="msgAlert">\n' +
' <div class="title">\n' +
' <span class="close">×</span>\n' +
' </div>\n' +
' <div class="content">' + msg + '</div>\n' +
' <div class="btn-box">\n' +
' <input type="button" value="确定" class="ok">\n' +
' <input type="button" value="取消" class="cancel">\n' +
' </div>\n' +
' </div>\n' +
'</div>');
$('#msgAlert').addClass('alert-show');
$('#msgAlert').on('click', '.ok', function () {
callback();
});
$('#msgAlert').on('click', '.close', function () {
that.destroy();
});
$('#msgAlert').on('click','.cancel',function () {
that.destroy();
})
};
this.destroy = function () {
$('#msgAlert').on('animationend', function () {
$('#msgAlertMask').remove();
});
$('#msgAlert').addClass('alert-hide');
}
}
window.pop = new MsgAlert();
$('#btn-alert').click(function () {
pop.alert('你说呢');
})
CSS
<style>
#msgAlertMask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
z-index: 999;
}
#msgAlert {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
min-width: 300px;
background: #fff;
-webkit-background-clip: content;
border-radius: 2px;
box-shadow: 1px 1px 50px rgba(0, 0, 0, .3);
}
#msgAlert .title {
padding: 0 14px 0 20px;
height: 42px;
line-height: 42px;
border-bottom: 1px solid #eee;
font-size: 14px;
color: #333;
overflow: hidden;
background-color: #F8F8F8;
border-radius: 2px 2px 0 0;
text-align: right;
}
#msgAlert .title .close {
font-size: 24px;
cursor: pointer;
}
#msgAlert .content {
padding: 30px 24px 40px;
}
#msgAlert .btn-box {
text-align: right;
padding: 0 15px 12px;
pointer-events: auto;
user-select: none;
-webkit-user-select: none;
}
#msgAlert .btn-box input {
height: 28px;
line-height: 28px;
margin: 5px 5px 0;
padding: 0 15px;
border: 1px solid #dedede;
background-color: #fff;
color: #333;
border-radius: 2px;
font-weight: 400;
cursor: pointer;
text-decoration: none;
}
#msgAlert .btn-box .ok {
border-color: #1E9FFF;
background-color: #1E9FFF;
color: #fff;
}
.alert-show {
animation: alert-show 0.1s ease-out forwards;
}
.alert-hide {
animation: alert-hide 0.1s ease-out forwards;
}
@keyframes alert-show {
0% {
opacity: 0;
transform: translate(-50%, -50%) scale(0);
}
100% {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
}
@keyframes alert-hide {
0% {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
100% {
opacity: 0;
transform: translate(-50%, -50%) scale(0);
}
}
</style>
总结:
- 动画效果还不够好,而且有bug,确认框回调里使用提示框的话会有问题,因为两者用的是同样的id,这个可能需要动态生成id来解决冲突问题
- 弹出框鼠标拖拽、窗口resize()事件、初始化时的参数设置等等也没有
- 通过transform:translate(-50%,-50%)方式居中好像会出现字和边框模糊的问题,难道layui是为了避免此问题,才动态给弹出框赋top、left?
- 还差得太远,继续加油吧
原文地址:https://www.cnblogs.com/Grani/p/11029416.html
时间: 2024-10-12 15:54:41