JS | 原生js仿ElementUI消息提示组件,含生命周期钩子

#编程技术 2023-03-04 11:17:48 | 全文 1019 字,阅读约需 3 分钟 | 加载中... 次浏览

👋 相关阅读


仿ElementUI消息提示组件,含生命周期钩子

先来看看 ElementUI 消息提示组件 官网:https://element.eleme.cn/#/zh-CN/component/message

图片alt

本文实现效果:

图片alt

代码:

<!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>

via

原生js造轮子之—-仿ElementUI消息提示组件,含生命周期钩子 | 码农家园 https://www.codenong.com/cs106344142/

·




×