利用es6和es5的继承方式写一个简单的弹窗

本片博文受到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标签引入,点击按钮查看效果就行了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值