本片博文受到https://blog.csdn.net/zfzhuman123/article/details/90411793的启发,es6部分代码只改了一点点,逻辑也是遵照他的思想来的,而且es5继承的部分也是用了部分es6的语法
1.首先是index.html
<!DOCTYPE html>
<html lang="en">
<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><link rel="stylesheet" href="http://at.alicdn.com/t/font_1117508_wxidm5ry7od.css"><style>/* message.css *//* 这个动画规则我们就叫做message-move-in吧,随后我们会用animation属性在某个元素上应用这个动画规则。 */@keyframes message-move-in {0% {/* 前边分析过了,弹出动画是一个自上而下的淡入过程 *//* 所以在动画初始状态要把元素的不透明度设置为0,在动画结束的时候再把不透明度设置1,这样就会实现一个淡入动画 */opacity: 0;/* 那么“自上而下”这个动画可以用“transform”变换属性结合他的“translateY”上下平移函数来完成 *//* translateY(-100%)表示动画初始状态,元素在实际位置上面“自身一个高度”的位置。 */transform: translateY(-100%);}100% {opacity: 1;/* 平移到自身位置 */transform: translateY(0);}}/* message.css */@keyframes message-move-out {0% {opacity: 1;transform: translateY(0);}100% {opacity: 0;transform: translateY(-100%);}}/* message.css */#message-container .message.move-in, #container .message.move-in {/* animation属性是用来加载某个动画规则 请参考 https://developer.mozilla.org/zh-CN/docs/Web/CSS/animation */animation: message-move-in 0.3s ease-in-out;/*ease-in-out 规定以慢速开始和结束的过渡效果(等于 cubic-bezier(0.42,0,0.58,1))(相对于匀速,(开始和结束都慢)两头慢)。*/}#message-container .message.move-out, #container .message.move-out {animation: message-move-out 0.3s ease-in-out;/* 让动画结束后保持结束状态 */animation-fill-mode: forwards;}/* message.css */#message-container, #container {position: absolute;left: 0;top: 0;right: 0;bottom: 0;background: #eee;/* 采用flex弹性布局,让容器内部的所有消息可以水平居中,还能任意的调整宽度 */display: flex;flex-direction: column;justify-content: center;align-items: center;}#message-container .message, #container .message {background: #fff;margin: 10px 0;padding: 0 10px;height: 40px;box-shadow: 0 0 10px 0 #eee;font-size: 14px;border-radius: 3px;/* 让消息内部的三个元素(图标、文本、关闭按钮)可以垂直水平居中 */display: flex;align-items: center;}/* 给每个图标都加上不同的颜色,用来区分不同类型的消息 */.message .icon-info {color: #0482f8;}.message .icon-error {color: #f83504;}.message .icon-success {color: #06a35a;}.message .icon-warning {color: #ceca07;}.message .icon-loading {color: #0482f8;} .btn {position: absolute;top: 10px;left: 10px;z-index: 100;}</style>
</head>
<body><button class="btn">弹窗消息提醒</button>
</body>
<script src="index.js"></script>
<script>
// message可以定义为全局对象,项目中可以直接调用。
const message = new Message({containerId: 'container'});
document.querySelector('.btn').addEventListener('click', () => {message.show({type: 'error',text: '点我旁边的叉叉试试',duration: 1000, // 不会自动消失closeable: true, // 可手动关闭});
});
</script>
</html>
2.es6部分
class Message {//构造函数会在实例化的时候自动执行constructor(opts={}) {const containerId = opts.containerId || 'message-container';// 检测下html中是否已经有这个message-container元素this.containerEl = document.getElementById(containerId);//没有就创建一个if (!this.containerEl) {// 创建一个Element对象,也就是创建一个id为message-container的dom节点this.containerEl = document.createElement('div');this.containerEl.id = containerId;// 把message-container元素放在html的body末尾document.body.appendChild(this.containerEl);}}show({ type = 'success', text = '', duration = 2000, closeable = false }) {// 创建一个Element对象let messageEl = document.createElement('div');// 设置消息class,这里加上move-in可以直接看到弹出效果messageEl.className = 'message move-in';// 消息内部html字符串messageEl.innerHTML = `<span class="icon icon-${type}"></span><div class="text">${text}</div>`;//点击弹窗提醒按钮,不能多次出现弹窗if(document.getElementsByClassName(messageEl.className).length>0) {alert('弹窗已存在');return;}// 是否展示关闭按钮if (closeable) {// 创建一个关闭按钮let closeEl = document.createElement('div');closeEl.className = 'close icon icon-close';// 把关闭按钮追加到message元素末尾messageEl.appendChild(closeEl);// 监听关闭按钮的click事件,触发后将调用我们的close方法// 我们把刚才写的移除消息封装为一个close方法closeEl.addEventListener('click', (e) => {this.close(messageEl)});}// 追加到message-container末尾// this.containerEl属性是我们在构造函数中创建的message-container容器this.containerEl.appendChild(messageEl);// 只有当duration大于0的时候才设置定时器,这样我们的消息就会一直显示if (duration > 0) {// 用setTimeout来做一个定时器setTimeout(() => {//this.close(messageEl);}, duration);} }/*** 关闭某个消息* 由于定时器里边要移除消息,然后用户手动关闭事件也要移除消息,所以我们直接把移除消息提取出来封装成一个方法* @param {Element} messageEl */close(messageEl) {// 首先把move-in这个弹出动画类给移除掉,要不然会有问题,可以自己测试下messageEl.className = messageEl.className.replace('move-in', '');// 增加一个move-out类messageEl.className += 'move-out';// 这个地方是监听动画结束事件,在动画结束后把消息从dom树中移除。// 如果你是在增加move-out后直接调用messageEl.remove,那么你不会看到任何动画效果messageEl.addEventListener('animationend', () => {// Element对象内部有一个remove方法,调用之后可以将该元素从dom树种移除!messageEl.remove();});}
}
3.es5方法
function Message(opts) {var defaultOpts = {containerId: opts.containerId||'message-container'};const containerId = defaultOpts.containerId;// 检测下html中是否已经有这个message-container元素this.containerEl = document.getElementById(containerId);//没有就创建一个if (!this.containerEl) {// 创建一个Element对象,也就是创建一个id为message-container的dom节点this.containerEl = document.createElement('div');this.containerEl.id = containerId;// 把message-container元素放在html的body末尾document.body.appendChild(this.containerEl);}
}//弹窗出现
Message.prototype.show = function(opts) {//es6的语法--解构赋值var defaultOpts = {type: opts.type||'success',text: opts.text||'点我旁边的叉叉试试',duration: opts.duration||2000, // 不会自动消失closeable: opts.closeable||true, // 可手动关闭}let {type,text,duration,closeable} = defaultOpts;// 创建一个Element对象let messageEl = document.createElement('div');// 设置消息class,这里加上move-in可以直接看到弹出效果messageEl.className = 'message move-in';// 消息内部html字符串messageEl.innerHTML = `<span class="icon icon-${type}"></span><div class="text">${text}</div>`;//点击弹窗提醒按钮,不能多次出现弹窗if(document.getElementsByClassName(messageEl.className).length>0) {alert('弹窗已存在');return;}// 是否展示关闭按钮if (closeable) {// 创建一个关闭按钮let closeEl = document.createElement('div');closeEl.className = 'close icon icon-close';// 把关闭按钮追加到message元素末尾messageEl.appendChild(closeEl);// 监听关闭按钮的click事件,触发后将调用我们的close方法// 我们把刚才写的移除消息封装为一个close方法closeEl.addEventListener('click', (e) => {this.close(messageEl)});}// 追加到message-container末尾// this.containerEl属性是我们在构造函数中创建的message-container容器this.containerEl.appendChild(messageEl);// 只有当duration大于0的时候才设置定时器,这样我们的消息就会一直显示if (duration > 0) {// 用setTimeout来做一个定时器setTimeout(() => {//this.close(messageEl);}, duration);}
}//弹窗消失
Message.prototype.close = function(messageEl) {// 首先把move-in这个弹出动画类给移除掉,要不然会有问题,可以自己测试下messageEl.className = messageEl.className.replace('move-in', '');// 增加一个move-out类messageEl.className += 'move-out';// 这个地方是监听动画结束事件,在动画结束后把消息从dom树中移除。// 如果你是在增加move-out后直接调用messageEl.remove,那么你不会看到任何动画效果messageEl.addEventListener('animationend', () => {// Element对象内部有一个remove方法,调用之后可以将该元素从dom树种移除!messageEl.remove();});
}
然后各自将es6或者es5这部分js在index.html中使用script标签引入,点击按钮查看效果就行了