模拟layui弹出层

Posted grani

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模拟layui弹出层相关的知识,希望对你有一定的参考价值。

以前觉得自己手写一个类似layui的弹出层是挺遥远的事,因为完全没有头绪,即便在layui官网知道layui使用的都是C3动画
之前试过控制width:0;height:0来做动画,结果惨不忍睹,直到几天前灵机一动联想到了tranform的scale属性,才稍微触及到了皮毛

为了不添加格外的html结构,所以弹出层也是动态生成
layui弹出框和遮罩层是同级结构,而我把弹出框放遮罩层里了,所以关闭时要用animationend来监听,弹出框做完动画后才删除遮罩层
确认框confirm之前也想跟原生confirm一样,通过返回布尔值来进行流程控制,结果为undefined,因为在调用时就已经返回了,而不是点了“确定“”才有返回值,这里和原生的一样,所以跟layui一样使用callback

HTML

<input type="button" value="模拟layui弹出层" id="btn-alert">

JS

 function MsgAlert() 
        this.alert = function (msg, time) 
            var delay = time || 1200,
                that = this;

            $('body').append('<div id="msgAlertMask">\n' +
                '    <div id="msgAlert">\n' +
                '        <div class="title">\n' +
                '            <span class="close">×</span>\n' +
                '        </div>\n' +
                '        <div class="content">' + msg + '</div>\n' +
                '    </div>\n' +
                '</div>');

            $('#msgAlert').addClass('alert-show');

            $('#msgAlert').on('click', '.close', function () 
                that.destroy();
            );

            setTimeout(function () 
                that.destroy();
            , delay);
        ;

        this.confirm = function (msg, callback) 
            var that = this;

            $('body').append('<div id="msgAlertMask">\n' +
                '    <div id="msgAlert">\n' +
                '        <div class="title">\n' +
                '            <span class="close">×</span>\n' +
                '        </div>\n' +
                '        <div class="content">' + msg + '</div>\n' +
                '        <div class="btn-box">\n' +
                '            <input type="button" value="确定" class="ok">\n' +
                '            <input type="button" value="取消" class="cancel">\n' +
                '        </div>\n' +
                '    </div>\n' +
                '</div>');

            $('#msgAlert').addClass('alert-show');

            $('#msgAlert').on('click', '.ok', function () 
                callback();
            );

            $('#msgAlert').on('click', '.close', function () 
                that.destroy();
            );
            $('#msgAlert').on('click','.cancel',function () 
                that.destroy();
            )
        ;

        this.destroy = function () 
            $('#msgAlert').on('animationend', function () 
                $('#msgAlertMask').remove();
            );

            $('#msgAlert').addClass('alert-hide');
        
    

    window.pop = new MsgAlert();

    $('#btn-alert').click(function () 
        pop.alert('你说呢');
    )

CSS

<style>
        #msgAlertMask 
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.3);
            z-index: 999;
        

        #msgAlert 
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            min-width: 300px;
            background: #fff;
            -webkit-background-clip: content;
            border-radius: 2px;
            box-shadow: 1px 1px 50px rgba(0, 0, 0, .3);
        

        #msgAlert .title 
            padding: 0 14px 0 20px;
            height: 42px;
            line-height: 42px;
            border-bottom: 1px solid #eee;
            font-size: 14px;
            color: #333;
            overflow: hidden;
            background-color: #F8F8F8;
            border-radius: 2px 2px 0 0;
            text-align: right;
        

        #msgAlert .title .close 
            font-size: 24px;
            cursor: pointer;
        

        #msgAlert .content 
            padding: 30px 24px 40px;
        

        #msgAlert .btn-box 
            text-align: right;
            padding: 0 15px 12px;
            pointer-events: auto;
            user-select: none;
            -webkit-user-select: none;
        

        #msgAlert .btn-box input 
            height: 28px;
            line-height: 28px;
            margin: 5px 5px 0;
            padding: 0 15px;
            border: 1px solid #dedede;
            background-color: #fff;
            color: #333;
            border-radius: 2px;
            font-weight: 400;
            cursor: pointer;
            text-decoration: none;
        

        #msgAlert .btn-box .ok 
            border-color: #1E9FFF;
            background-color: #1E9FFF;
            color: #fff;
        

        .alert-show 
            animation: alert-show 0.1s ease-out forwards;
        

        .alert-hide 
            animation: alert-hide 0.1s ease-out forwards;
        

        @keyframes alert-show 
            0% 
                opacity: 0;
                transform: translate(-50%, -50%) scale(0);
            
            100% 
                opacity: 1;
                transform: translate(-50%, -50%) scale(1);
            
        

        @keyframes alert-hide 
            0% 
                opacity: 1;
                transform: translate(-50%, -50%) scale(1);
            
            100% 
                opacity: 0;
                transform: translate(-50%, -50%) scale(0);
            
        
    </style>

总结:

  1. 动画效果还不够好,而且有bug,确认框回调里使用提示框的话会有问题,因为两者用的是同样的id,这个可能需要动态生成id来解决冲突问题
  2. 弹出框鼠标拖拽、窗口resize()事件、初始化时的参数设置等等也没有
  3. 通过transform:translate(-50%,-50%)方式居中好像会出现字和边框模糊的问题,难道layui是为了避免此问题,才动态给弹出框赋top、left?
  4. 还差得太远,继续加油吧

以上是关于模拟layui弹出层的主要内容,如果未能解决你的问题,请参考以下文章

layui弹出层怎么不显示

adminlte+layui框架搭建3 - layui弹出层

LAYUI弹出层详解

关于layui弹出层的使用

layui使用layer弹出层父子页面事件相互调用方法

layui的弹出层效果在导航中的使用