zl程序教程

您现在的位置是:首页 >  后端

当前栏目

原生js造轮子之----仿ElementUI消息提示组件,含生命周期钩子

JS组件消息elementui 提示 原生 ---- 生命周期
2023-09-11 14:22:30 时间

先来看看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>