模拟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. 还差得太远,继续加油吧

原文地址:https://www.cnblogs.com/Grani/p/11029416.html

时间: 2024-10-12 15:54:41

模拟layui弹出层的相关文章

layer/layui弹出层插件bug

<button class="layui-btn" lay-submit lay-filter="formDemo" id="layui-btn" type="submit">立即提交</button> 使用layer/layui弹出层插件,type="submit"时,弹出层失效,改为type="button"时正常弹出;

layui弹出层

利用layui框架layer部分执行的弹出层,这样比起普通alert的弹出层更美观 首先,写一个按钮 <button class='btn'>点击试试</button> js部分 $(document).ready(function () { $('.btn').on('click', function () { layer.confirm('你好吗?', { btn: ['好', '不好'] }, function () { layer.msg('hao', { icon: 1

layui弹出层type=2无法正常验证问题

思路:在弹出层页面form表单中增加一个隐藏的提交按钮,当弹出层点击确定按钮时,触发弹出层页面中的隐藏按钮,触发提交校验 弹出层脚本如下: function LoadDemo(id) { layer.open({ title: '弹出层标题', //弹出层标题 type: 2, content: 'demo.shtml', btn: ['确定', '关闭'], area: ["650px", "550px"], success: function (layero,

LAYUI弹出层详解

今天空了学习一下弹出层 还是一步步展示把 首先,layer可以独立使用,也可以通过Layui模块化使用.我个人一直是用的模块化的 所以下面素有的都是基于模块化的. 引入好相关文件就可以开始啦  今天放图片把 试着学一下放图片 1.最简单的弹层,这个弹层的效果其实就是一个加了特效和样式的alert();代码如下: <script>layui.use("layer", function () {var layer = layui.layer;layer.msg("大家

layui弹出层layer过大被遮挡解决办法-resize事件自动调整

遇到的问题 ??最近在使用layui做一个管理系统,由于前端技术有限,在开发过程中也遇到这样那样的问题,即比较简单的问题有时也要搞半天..??layer弹出窗口在弹出时指定了area,弹出后,如果当前页面(iframe)大小比弹出的窗口小,那么就会出现无法操作弹出窗口的尴尬情况.查看官方文档以及搜索引擎,都没有找到好的办法.如图所示: 弹出窗口比当前页面大 ??这时,唯有放大整个页面才能看到完全的弹出窗口,才可以操作. 我的尝试 ??我的思路时通过监听页面的resize事件,通过layer.st

layUI 几个简单的弹出层

导入控件主题 <link rel="stylesheet" href="dist/themes/default/style.min.css" /> 创建容器 也就是包含jsTree控件的元素,一般使用<div>就可以了. <div id="jstree_demo_div"></div> 引入jQuery jsTree依赖于jQuery,所以需要引入jQuery: <script src=&qu

layui(弹出层)

首先引入文件 layui.css jquery.min.js layui.js 弹出层 data-method 后面的属性控制是什么弹窗,在js中写方法 <div class="site-demo-button" id="layerDemo" style="margin-bottom: 0;"> <button data-method="setTop" class="layui-btn"&

权限管理系统之LayUI实现页面增删改查和弹出层交互

由于对LayUI框架不太熟悉,昨天抽空看了下LayUI的文档,今天在网上找了使用LayUI进行增删改查相关内容,自己照葫芦画了个瓢,画瓢部分不是很难,主要是下午遇到了一个弹出层的问题耗时比较久. 同一项目,设计风格都差不多,对于涉及单个数据表的页面,基本都是增删改查,布局都是差不多,实际项目中都是复制.粘贴过来改下数据基本就能完成80%,后续就是修修补补或者是要实现一些特殊需求,记得刚参加工作时,老大直接给了一个已经做好的模板页面让我比对着手动敲一遍,当时觉得重复操作没啥用,现在再看觉得作用很大

弹出层-layui

type 0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层) iframe窗 layer.open({ type: 2, title: '添加文章', shadeClose: false,//点击阴影是否关闭 shade: 0.3,//阴影透明度,false为0,true为1 maxmin: true, //开启最大化最小化按钮 area: ['1200px', '700px'], content: '/System/Article/AddArticle' }) 页面