仿ElementUI消息提示组件,含生命周期钩子
先来看看 ElementUI 消息提示组件 官网:https://element.eleme.cn/#/zh-CN/component/message
本文实现效果:
代码:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style type="text/css">
div,
i,
button {
margin: 0;
padding: 0;
}
/*预定义样式,通过js动态生成dom时,加上指定类名*/
.dpn-message {
font-family: "\5FAE\8F6F\96C5\9ED1", Helvetica, sans-serif;
font-size: 12px;
z-index: 99999;
}
.dpn-message {
box-sizing: border-box;
position: fixed;
top: -200px;
left: 50%;
transform: translateX(-50%);
z-index: 99999;
padding: 15px;
padding-right: 32px;
min-width: 20%;
max-width: 50%;
border-radius: 4px;
transition: top .3s;
}
/*info 消息*/
.dpn-message.dpn-info {
background: #EDF2FC;
border: 1px solid #EBEEF5;
color: #909399;
}
/*success消息*/
.dpn-message.dpn-success {
background: #f0f9eb;
border: 1px solid #e1f3d8;
color: #67C23A;
}
/*error消息*/
.dpn-message.dpn-error {
background: #fef0f0;
border: 1px solid #fde2e2;
color: #F56C6C;
}
/*warning消息*/
.dpn-message.dpn-warning {
background: #fdf6ec;
border: 1px solid #faecd8;
color: #E6A23C;
}
.dpn-message .dpn-close {
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
width: 16px;
height: 16px;
line-height: 16px;
text-align: center;
font-style: normal;
cursor: pointer;
}
</style>
</head>
<body>
<button id="submit1">info</button>
<button id="submit2">success</button>
<button id="submit3">error</button>
<button id="submit4">warning</button>
</body>
<script type="text/javascript">
class MessageBox {
constructor(options) {
// 把传递进来的配置信息挂载到实例上(以后可以基于实例在各个方法各个地方拿到这个信息)
for(let key in options) {
if(!options.hasOwnProperty(key)) break;
this[key] = options[key];
}
// 开始执行
this.init();
}
// 初始化:通过执行INIT控制逻辑的进行
init() {
if(this.status === "message") {
this.createMessage();
this.open();
return;
}
}
// 创建元素
createMessage() {
this.messageBox = document.createElement('div');
this.messageBox.className = `dpn-message dpn-${this.type}`;
this.messageBox.innerHTML = `
${this.message}
<i class="dpn-close">X</i>
`;
document.body.appendChild(this.messageBox);
// 基于事件委托监听关闭按钮的点击
this.messageBox.onclick = ev => {
let target = ev.target;
//判断点击的元素是否为关闭按钮
if(target.className === "dpn-close") {
// 点击的是关闭按钮
this.close();
}
};
// 钩子函数
this.oninit();
}
// 控制显示
open() {
if(this.status === "message") {
let messageBoxs = document.querySelectorAll('.dpn-message'),
len = messageBoxs.length;
//计算新弹出的messageBox的Y轴偏移量
this.messageBox.style.top = `${len===1 ? 20:20+(len-1)*70}px`;
// 如果duration不为零,控制自动消失
this.autoTimer = setTimeout(() => {
this.close();
}, this.duration);
// 钩子函数
this.onopen();
return;
}
}
// 控制隐藏
close() {
if(this.status === "message") {
clearTimeout(this.autoTimer);
this.messageBox.style.top = '-200px';
let anonymous = () => {
document.body.removeChild(this.messageBox);
// 钩子函数
this.onclose();
};
this.messageBox.addEventListener('transitionend', anonymous);
return;
}
}
}
//全局对象上挂载该方法
window.messageplugin = function(options = {}) {
//允许只传入字符串,对其进行对象格式处理
if(typeof options === "string") {
options = {
message: options
};
}
//用户提供的配置覆盖默认配置项
options = Object.assign({
status: 'message',
message: '我是默认信息',
type: 'info',
duration: 3000,
//生命周期钩子
oninit() {},
onopen() {},
onclose() {},
}, options);
return new MessageBox(options);
};
let submit1 = document.getElementById("submit1")
let submit2 = document.getElementById("submit2")
let submit3 = document.getElementById("submit3")
let submit4 = document.getElementById("submit4")
submit1.onclick = function() {
messageplugin('我是info');
};
submit2.onclick = function() {
messageplugin({
message: "我是success",
type: "success"
});
};
submit3.onclick = function() {
messageplugin({
message: "我是error",
type: "error"
});
};
submit4.onclick = function() {
messageplugin({
message: "我是warning",
type: "warning",
oninit() { console.log('我被init 了') },
onopen() { console.log('我被open 了') },
onclose() { console.log('我被close 了') },
});
};
</script>
</html>
原生js造轮子之—-仿ElementUI消息提示组件,含生命周期钩子 | 码农家园 https://www.codenong.com/cs106344142/