layui自定义弹窗组件

Layui 自定义弹窗组件使用

本文方法依赖于Layui弹窗插件、Bootstrap整体布局,在此基础上遵循组件化开发原则自定义弹窗标题、内容格式开发高度自适应的弹窗组件,弹窗内容依旧使用iframe进行展示。

 

编写弹窗组件 popup.js

 

(function ($) {
    "use strict";
    let resizeTimer = null;
    let popup_id = 0;
    /*
     * Popup组件基于jquery,layUI, Bootstrap使用时要引用相应的js
     * param: {
     *      id: "popup" 防止唯一弹窗重复弹出 id不可重复
     *      url: "" 界面URL
     *      skin: 'layui-layer-rim' 皮肤定制、自定义样式
     *      offset: 'rb' 弹窗位置
     *      defaultWidth: 740 layer弹窗初始宽度
     *      time : 0 自动关闭所需毫秒
     *      anim: 0 弹出动画
     *      shadeClose: false 是否点击遮罩关闭
     *      shade : 0 遮罩
     * },
     *
     * offset支持:查看layUI弹窗offset属性
     * anim支持:查看layUI弹窗anim属性
     *
     *
     * 使用:$(document).popup(params);
     */
    function Popup(obj, params) {
        popup_id += 1;
        this.tiggerObj = obj;
        this.param = params || {};
        this.popupHeadInit()
        this.popupParamsInit()
        this.popupInitEvent();
    }
    Popup.prototype.popupHeadInit = function () {
        let self = this;
        let popup = "";
        popup += '<div id="popup_layer_' + popup_id + '">';
        popup += '<div class="panel-group" style="margin-bottom: -20px;">';
        popup += '<div class="panel panel-default fadein fadeout" style="border: 0px;">';
        popup += '<div class="panel-heading" data-toggle="collapse" style="cursor:pointer;">';
        popup += '<h3 class="panel-title text-center">';
        popup += '<span>' + self.param.title + '</span>';
        popup += '<span class="glyphicon pull-right glyphicon-remove-circle top-right" role="popup_close"></span>';
        popup += '<span style="font-size: 8px;position: absolute;right: 50px;top: 14px;">触发时间:' + self.param.occur_time + '</span>';
        popup += '</h3>';
        popup += '</div>';
        popup += '<div class="panel-body" style="padding: 0;">';
        popup += '<iframe id="popup_layer_iframe_' + popup_id + '" name="popup_layer_iframe_' + popup_id + '" ' +
            'src="' + self.param.url + '" width="100%" frameborder="0" scrolling="auto"></iframe>';
        popup += '</div>';
        popup += '</div>';
        popup += '</div>';
        self.popup = $(popup);
        $(document.body).append(self.popup);
    }
    Popup.prototype.popupParamsInit = function () {
        if (this.param.skin === undefined || this.param.skin === '') {
            this.param.skin = 'layui-layer-rim';
        }
        if (this.param.offset === undefined || this.param.offset === '') {
            this.param.offset = 'rb';
        }
        if (this.param.defaultWidth === undefined || this.param.defaultWidth === '') {
            this.param.defaultWidth = 740;
        }
        if (this.param.id === undefined || this.param.id === '') {
            this.param.id = popup_id;
        }
        if (this.param.time === undefined || this.param.time === '') {
            this.param.time = 0;
        }
        if (this.param.anim === undefined || this.param.anim === '') {
            this.param.anim = 2;
        }
        if (this.param.shadeClose === undefined || this.param.shadeClose === '') {
            this.param.shadeClose = false;
        }
        if (this.param.shade === undefined || this.param.shade === '') {
            this.param.shade = 0;
        }
        if (this.param.title === undefined || this.param.title === '') {
            this.param.title = "title";
        }
        if (this.param.occur_time === undefined || this.param.occur_time === '') {
            this.param.occur_time = "2020";
        }
    }
    Popup.prototype.popupInitEvent = function () {
        let self = this;
        layer.open({
            type: 1,
            // type: 2,
            shade: self.param.shade,
            title: false,
            closeBtn: 0,
            time: self.param.time,
            anim: self.param.anim,
            shadeClose: self.param.shadeClose,
            offset: self.param.offset, //弹窗位置
            resize: false, //是否允许拉伸
            id: "layer_open_" + self.param.id, //设定一个id,防止重复弹出
            scrollbar: false,
            area: [self.param.defaultWidth + 'px'],
            skin: self.param.skin, //加上边框
            // content: self.param.url,
            content: self.popup,
            success: function (layers, index) {
                //绑定关闭事件
                layers.find("[role='popup_close']").on("click", function (){
                    layer.close(index);
                });
                self.popupSetLayerPopup(layers, index);
                $(window).bind('resize', function () {
                    if (resizeTimer) clearTimeout(resizeTimer);
                    resizeTimer = setTimeout(function () {
                        self.popupSetLayerPopup(layers, index);
                    }, 100);
                });
            },end: function(){
                self.popup.remove();
            }
        });
    };
    Popup.prototype.popupSetLayerPopup = function (layers, index) {
        let self = this;
        if (self.iframeHeight === undefined) {
            $("#popup_layer_iframe_" + popup_id).on('load', function () {
                let frameObj = document.getElementById("popup_layer_iframe_" + popup_id).contentDocument ||
                    document.getElementById("popup_layer_iframe_" + popup_id).contentWindow.document;
                self.iframeHeight = frameObj.documentElement.scrollHeight;
                self.layerPopupAdaptive(layers, index);
            });
        } else {
            self.layerPopupAdaptive(layers, index);
        }
    };
    Popup.prototype.layerPopupAdaptive = function (layers, index) {
        let self = this;
        let unknownPixel = 3;//未知的3个像素 发生于panel-body
        let documentHeight = $(document).height();
        let documentWidth = $(document).width();
        let popup_head = layers.find('.panel-heading');
        let popup_head_height = parseInt(popup_head.innerHeight());
        let layer_border_width = parseInt(layers.css("border-top-width")) + parseInt(layers.css("border-bottom-width"));
        let layerWidth = layers.width();
        let layerHeight;
        let top = 0;
        let left = 0;
        if (self.iframeHeight > documentHeight) {
            layerHeight = documentHeight - layer_border_width - popup_head_height - unknownPixel;
        } else {
            layerHeight = self.iframeHeight;
            top = documentHeight - self.iframeHeight - layer_border_width - popup_head_height - unknownPixel;
        }
        if (layerWidth > documentWidth) {
            layerWidth = documentWidth;
        } else {
            layerWidth = self.param.defaultWidth;
            left = documentWidth - layerWidth;
        }
        layers.children(":first").css({"height": (layerHeight + popup_head_height + unknownPixel) + "px"})
        $("#popup_layer_iframe_" + popup_id).css({"height": layerHeight + "px"});
        let computeOffset = self.computeOffset(top, left);
        layer.style(index, {
            "top": computeOffset.top + "px",
            "left": computeOffset.left + "px",
            "width": layerWidth + "px"
        });
    }
    Popup.prototype.computeOffset = function (top, left) {
        let self = this;
        if (self.param.offset === 'rb') {//居右下角
            //组件默认计算指标为右下角
        } else if (self.param.offset === 'lt') {//居左上角
            top = 0;
            left = 0;
        } else if (self.param.offset === 'lb') {//居左下角
            left = 0;
        } else if (self.param.offset === 'rt') {//居右上角
            top = 0;
        } else if (self.param.offset === 'r') {//居右
            top = top / 2;
        } else if (self.param.offset === 'b') {//居下
            left = left / 2;
        } else if (self.param.offset === 'l') {//居左
            top = top / 2;
            left = 0;
        } else if (self.param.offset === 't') {//居上
            top = 0;
            left = left / 2;
        } else if (self.param.offset === 'auto') {//居中
            top = top / 2;
            left = left / 2;
        } else {
            if (Array.isArray(self.param.offset)) {
                top = Number(self.param.offset[0].replace(/\s+|px/gi, ""));
                left = Number(self.param.offset[1].replace(/\s+|px/gi, ""));
            } else {
                let num = self.param.offset.replace(/\s+|px/gi, "");
                let toNum;
                toNum = Number(num);
                top = toNum;
                left = toNum;
            }
        }
        return {top: top, left: left};
    }
    $.fn.popup = function (options) {
        return new Popup(this, options);
    };
})(jQuery);

 

 

 

 

 

组件使用方法

  • 引入依赖项

 

<script src="/webjars/jquery/jquery.min.js"></script>
<link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<script src="/webjars/bootstrap/js/bootstrap.min.js"></script>
<link href="/static/layui/css/layui.css" rel="stylesheet">
<script src="/static/layui/layui.js"></script>

 

  • 引入组件
<script src="/static/common/popup.js"></script>

 

posted @ 2020-08-04 17:47  向死而生i  阅读(1784)  评论(0)    收藏  举报