mirror of
https://github.com/skyle1995/NetworkAuth.git
synced 2026-05-25 02:24:05 +08:00
201 lines
6.5 KiB
JavaScript
201 lines
6.5 KiB
JavaScript
|
|
/**
|
|||
|
|
* 抽屉模块
|
|||
|
|
*/
|
|||
|
|
layui.define(['jquery', 'layer'], function (exports) {
|
|||
|
|
('use strict');
|
|||
|
|
|
|||
|
|
var MOD_NAME = 'drawer';
|
|||
|
|
var $ = layui.jquery;
|
|||
|
|
var layer = layui.layer;
|
|||
|
|
|
|||
|
|
layui.link(layui.cache.base + 'drawer/drawer.css');
|
|||
|
|
var drawer = new (function () {
|
|||
|
|
this.open = function (option) {
|
|||
|
|
return layerDrawer(option);
|
|||
|
|
};
|
|||
|
|
this.title = layer.title;
|
|||
|
|
this.style = layer.style;
|
|||
|
|
this.close = layer.close;
|
|||
|
|
this.closeAll = layer.closeAll;
|
|||
|
|
})();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
*
|
|||
|
|
* 封装 layer.open
|
|||
|
|
*
|
|||
|
|
* @param {object} option, `type`, `anim`, `move`, `fixed`, `skin`,`maxWidth`, `maxHeight`, `moveOut`, `moveEnd` 不可用,其它参数和 layer.open 一致, 新增 `iframe`和 `url`参数
|
|||
|
|
* @returns {number} 原生 layer 的 index
|
|||
|
|
*/
|
|||
|
|
function layerDrawer(option) {
|
|||
|
|
var opt = normalizeOption(option);
|
|||
|
|
if (opt.target) appendToTarget(opt);
|
|||
|
|
if (opt.url) loadFragment(opt);
|
|||
|
|
if (opt.shade) {
|
|||
|
|
$('<style/>')
|
|||
|
|
.attr('id', 'layer-drawer')
|
|||
|
|
.html('.layui-layer-shade{opacity: 0;transition: opacity .35s cubic-bezier(0.34, 0.69, 0.1, 1);}') // fadeIn
|
|||
|
|
.appendTo('head');
|
|||
|
|
|
|||
|
|
option.end = Aspect(option.end, undefined, function (layero, index) {
|
|||
|
|
$('#layer-drawer').remove();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
return layer.open(opt);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 加载 HTML 片段到 layer content
|
|||
|
|
* @param {object} option 设置选项
|
|||
|
|
*/
|
|||
|
|
function loadFragment(option) {
|
|||
|
|
option.success = Aspect(option.success, function (layero) {
|
|||
|
|
$.ajax({
|
|||
|
|
url: option.url,
|
|||
|
|
dataType: 'html',
|
|||
|
|
success: function (result) {
|
|||
|
|
layero.children('.layui-layer-content').html(result);
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
*将 layer 附加到指定节点
|
|||
|
|
* @param {object} opt 设置选项
|
|||
|
|
*/
|
|||
|
|
function appendToTarget(opt) {
|
|||
|
|
var targetDOM = $(opt.target);
|
|||
|
|
var contentDOM = opt.content;
|
|||
|
|
|
|||
|
|
contentDOM.appendTo(targetDOM);
|
|||
|
|
opt.skin = getDrawerAnimationClass(opt.offset, true);
|
|||
|
|
opt.offset = calcOffset(opt.offset, opt.area, targetDOM);
|
|||
|
|
// 处理关闭后偶现 DOM 仍显示的问题
|
|||
|
|
opt.end = Aspect(opt.end, function () {
|
|||
|
|
contentDOM.css('display', 'none');
|
|||
|
|
});
|
|||
|
|
if (opt.shade) {
|
|||
|
|
opt.success = Aspect(opt.success, function (layero, index) {
|
|||
|
|
var shadeDOM = $('#layui-layer-shade' + index);
|
|||
|
|
shadeDOM.css('position', 'absolute');
|
|||
|
|
shadeDOM.appendTo(layero.parent());
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 规范化 layer.open 选项
|
|||
|
|
* @param {object} option layer.open 的选项
|
|||
|
|
* @returns 规范化后的选项
|
|||
|
|
*/
|
|||
|
|
function normalizeOption(option) {
|
|||
|
|
option.type = option.iframe ? 2 : 1;
|
|||
|
|
option.anim = -1;
|
|||
|
|
option.move = false;
|
|||
|
|
option.fixed = true;
|
|||
|
|
option.content = option.iframe ? option.iframe : option.content;
|
|||
|
|
if (option.offset === undefined) option.offset = 'r';
|
|||
|
|
option.area = calcDrawerArea(option.offset, option.area);
|
|||
|
|
option.skin = getDrawerAnimationClass(option.offset);
|
|||
|
|
if (option.title === undefined) option.title = false;
|
|||
|
|
if (option.closeBtn === undefined) option.closeBtn = false;
|
|||
|
|
if (option.shade === undefined) option.shade = 0.3;
|
|||
|
|
if (option.shadeClose === undefined) option.shadeClose = true;
|
|||
|
|
if (option.resize === undefined) option.resize = false;
|
|||
|
|
if (option.success === undefined) option.success = function () {}; // 处理遮罩需要
|
|||
|
|
if (option.end === undefined) option.end = function () {};
|
|||
|
|
return option;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 计算抽屉宽高
|
|||
|
|
* @param {string} offset 抽屉方向 l = 左, r = 右, t = 上, b = 下
|
|||
|
|
* @param {string[] | string} drawerArea 抽屉大小,字符串数组格式[width, height]:["200px","100%"],字符串格式:"30%" "200px"。
|
|||
|
|
* @returns{string[]} 抽屉宽高数组
|
|||
|
|
*/
|
|||
|
|
function calcDrawerArea(offset, drawerArea) {
|
|||
|
|
if (drawerArea instanceof Array) {
|
|||
|
|
return drawerArea;
|
|||
|
|
}
|
|||
|
|
drawerArea = drawerArea === undefined || drawerArea === 'auto' ? '30%' : drawerArea;
|
|||
|
|
if (offset === 'l' || offset === 'r') {
|
|||
|
|
return [drawerArea, '100%'];
|
|||
|
|
} else if (offset === 't' || offset === 'b') {
|
|||
|
|
return ['100%', drawerArea];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取抽屉动画类,指定挂载容器时需要设置绝对定位
|
|||
|
|
* @param {string} offset 抽屉方向 l = 左, r = 右, t = 上, b = 下
|
|||
|
|
* @param {boolean} [isAbsolute] 是否是绝对定位
|
|||
|
|
* @returns {string} 抽屉入场动画类
|
|||
|
|
*/
|
|||
|
|
function getDrawerAnimationClass(offset, isAbsolute) {
|
|||
|
|
var prefixClass = 'layer-drawer layer-drawer-anim layui-anim layer-anim-';
|
|||
|
|
var suffix = 'rl';
|
|||
|
|
if (offset === 'l') {
|
|||
|
|
suffix = 'lr';
|
|||
|
|
} else if (offset === 'r') {
|
|||
|
|
suffix = 'rl';
|
|||
|
|
} else if (offset === 't') {
|
|||
|
|
suffix = 'tb';
|
|||
|
|
} else if (offset === 'b') {
|
|||
|
|
suffix = 'bt';
|
|||
|
|
}
|
|||
|
|
return prefixClass + suffix + (isAbsolute ? ' position-absolute ' : '');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 指定挂载容器重新计算 offset
|
|||
|
|
*
|
|||
|
|
* layer 源码中使用窗口宽高计算位置,所以此
|
|||
|
|
* @param {string} offset 位置
|
|||
|
|
* @param {string | string[]} area 范围大小
|
|||
|
|
* @param {*} targetEl 挂载节点
|
|||
|
|
* @returns 包含抽屉位置信息的数组,[top, left]
|
|||
|
|
*/
|
|||
|
|
function calcOffset(offset, area, targetEl) {
|
|||
|
|
// https://gitee.com/layui/layui/blob/main/src/modules/layer.js#L560
|
|||
|
|
if (offset === undefined || offset === 'l' || offset === 't') {
|
|||
|
|
offset = 'lt';
|
|||
|
|
} else if (offset === 'r') {
|
|||
|
|
// https://gitee.com/layui/layui/blob/main/src/modules/layer.js#L554
|
|||
|
|
area = area instanceof Array ? area[0] : area;
|
|||
|
|
var left = /%$/.test(area)
|
|||
|
|
? targetEl.innerWidth() * (1 - window.parseFloat(area) / 100)
|
|||
|
|
: targetEl.innerWidth() - window.parseFloat(area);
|
|||
|
|
offset = ['0', left];
|
|||
|
|
} else if (offset === 'b') {
|
|||
|
|
area = area instanceof Array ? area[1] : area;
|
|||
|
|
var top = /%$/.test(area)
|
|||
|
|
? targetEl.innerHeight() * (1 - window.parseFloat(area) / 100)
|
|||
|
|
: targetEl.innerHeight() - window.parseFloat(area);
|
|||
|
|
offset = [top, '0'];
|
|||
|
|
}
|
|||
|
|
return offset;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 简易的切面
|
|||
|
|
* @param {Function} target 被通知的对象,原函数
|
|||
|
|
* @param {Function | undefined} [before] 前置通知
|
|||
|
|
* @param {Function | undefined} [after] 后置通知
|
|||
|
|
* @returns 代理函数
|
|||
|
|
*/
|
|||
|
|
function Aspect(target, before, after) {
|
|||
|
|
function proxyFunc() {
|
|||
|
|
if (before && typeof before === 'function') {
|
|||
|
|
before.apply(this, arguments);
|
|||
|
|
}
|
|||
|
|
target.apply(this, arguments);
|
|||
|
|
if (after && typeof after === 'function') {
|
|||
|
|
after.apply(this, arguments);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return proxyFunc;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
exports(MOD_NAME, drawer);
|
|||
|
|
});
|