TaoLer/public/static/component/pear/module/drawer.js

421 lines
11 KiB
JavaScript
Raw Normal View History

2023-03-16 22:40:15 +08:00
layui.define(['jquery', 'element', 'layer', 'loading'], function (exports) {
"use strict";
/**
* Drawer component
* */
var MOD_NAME = 'drawer',
$ = layui.jquery,
element = layui.element,
layer = layui.layer,
loading = layui.loading;
var drawer = new function () {
/**
* open drawer
* */
this.open = function (option) {
// 默认使用 legacy 模式
if (option.legacy === undefined) {
option.legacy = true;
};
if (option.legacy) {
var obj = new mSlider({
target: option.target,
dom: option.dom,
direction: option.direction,
distance: option.distance,
time: option.time ? option.time : 0,
maskClose: option.maskClose,
callback: option.success
});
obj.open();
return obj;
} else {
return layerDrawer(option);
}
}
this.title = layer.title;
this.style = layer.style;
this.close = layer.close;
this.closeAll = layer.closeAll;
}
/**
*
* 封装 layer.open
* type,anim,move,fixed不可用,其它参数和 layer.open 一致
* @param {LayerOption} option
* @returns 原生 layer index
*/
function layerDrawer(option) {
var opt = normalizeOption(option)
if (opt.target) appendToTarget(opt);
if (opt.url) loadFragment(opt);
var layerIndex = layer.open(opt);
return layerIndex;
}
/**
* 加载 HTML 片段到 layer content
* @param {*} option
*/
function loadFragment(option) {
option.success = Aspect(option.success, function (layero, index) {
var layerID = "#" + layero.attr("id");
loading.block({
type: 1,
elem: layerID,
msg: ''
});
$.ajax({
url: option.url,
dataType: "html",
success: function (result) {
layero.children('.layui-layer-content').html(result);
loading.blockRemove(layerID);
}
})
})
}
/**
* 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 仍显示的问题layer 的 BUG
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 选项兼容原版 Drawer 所有选项
* @param {LayerOption} option layer.open 的选项
* @returns 规格化后的 layer.open 选项
*/
function normalizeOption(option) {
if (option.direction && !option.offset) {
if (option.direction === "right") {
option.offset = "r";
} else if (option.direction === "left") {
option.offset = "l";
} else if (option.direction === "top") {
option.offset = "t";
} else if (option.direction === "bottom") {
option.offset = "b";
} else {
option.offset = "r";
}
}
if (option.distance && !option.area) {
option.area = option.distance;
}
if (option.dom && !option.content) {
option.content = $(option.dom);
}
if (option.maskClose && option.shadeClose === undefined) {
option.shadeClose = (option.maskClose + "").toString() !== "false" ? true : false;
}
option.type = 1
option.anim = -1;
option.move = false;
option.fixed = true;
if (option.iframe) {
option.type = 2;
option.content = option.iframe;
}
if (option.offset === undefined) option.offset = "r";
option.area = calcDrawerArea(option.offset, option.area);
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.skin === undefined) option.skin = getDrawerAnimationClass(option.offset);
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]字符串格式百分比或单位 px
* @returns 抽屉宽高数组
*/
function calcDrawerArea(offset, drawerArea) {
if (drawerArea instanceof Array) {
return drawerArea;
}
if (drawerArea === undefined || drawerArea === "auto") {
drawerArea = "30%";
}
if (offset === "l" || offset === "r") {
return [drawerArea, "100%"];
} else if (offset === "t" || offset === "b") {
return ["100%", drawerArea];
}
return [drawerArea, "100%"];
}
/**
* 获取抽屉动画类
* @param {string} offset 抽屉方向
* @param {boolean} 是否 absolute 布局
* @returns 抽屉入场动画类
*/
function getDrawerAnimationClass(offset, isAbsolute) {
var positionAbsoluteClass = "position-absolute ";
var prefixClass = "pear-drawer pear-drawer-anim layui-anim layer-anim-";
var suffix = "rl";
if (isAbsolute) {
prefixClass = positionAbsoluteClass + prefixClass;
}
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;
}
/**
* 指定挂载容器重新计算 offset
* @param {*} offset 位置
* @param {*} area 范围大小
* @param {*} targetEl 挂载节点
* @returns 包含抽屉位置信息的数组[top,left]
*/
function calcOffset(offset, area, targetEl) {
if (offset === undefined || offset === "l" || offset === "t") {
offset = "lt";
} else if (offset === "r") {
var left;
if (area instanceof Array) {
area = area[0];
}
if (area.indexOf("%") != -1) {
left = targetEl.innerWidth() * (1 - area.replace("%", "") / 100);
} else {
left = targetEl.innerWidth() - area;
}
offset = [0, left];
} else if (offset === "b") {
var top;
if (area instanceof Array) {
area = area[1];
}
if (area.indexOf("%") != -1) {
top = targetEl.innerHeight() * (1 - area.replace("%", "") / 100);
} else {
top = targetEl.innerHeight() - area;
}
offset = [top, 0];
}
return offset;
}
/**
* 简易的切面
* @param {Function} func 被通知的对象原函数
* @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);
});
/**
* 源码
* */
(function (b, c) {
function a(d) {
this.opts = {
"target": d.target || "body",
"direction": d.direction || "left",
"distance": d.distance || "60%",
"dom": this.Q(d.dom),
"time": d.time || "",
"maskClose": (d.maskClose + "").toString() !== "false" ? true : false,
"callback": d.callback || ""
};
this.rnd = this.rnd();
this.target = this.opts.target;
this.dom = this.opts.dom[0];
this.wrap = "";
this.inner = "";
this.mask = "";
this.init()
}
a.prototype = {
Q: function (d) {
return document.querySelectorAll(d)
},
isMobile: function () {
return navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i) ? true : false
},
addEvent: function (f, e, d) {
if (f.attachEvent) {
f.attachEvent("on" + e, d)
} else {
f.addEventListener(e, d, false)
}
},
rnd: function () {
return Math.random().toString(36).substr(2, 6)
},
init: function () {
var g = this;
if (!g.dom) {
console.log("未正确绑定弹窗容器");
return
}
g.dom.style.display = "block"; // 兼容 layer 捕获层
var d = document.createElement("div");
var e = document.createElement("div");
var f = document.createElement("div");
d.setAttribute("class", "mSlider-main ms-" + g.rnd);
e.setAttribute("class", "mSlider-inner");
f.setAttribute("class", "mSlider-mask");
g.Q(g.target)[0].appendChild(d);
g.Q(".ms-" + g.rnd)[0].appendChild(e);
g.Q(".ms-" + g.rnd)[0].appendChild(f);
g.wrap = g.Q(".ms-" + g.rnd)[0];
g.inner = g.Q(".ms-" + g.rnd + " .mSlider-inner")[0];
g.mask = g.Q(".ms-" + g.rnd + " .mSlider-mask")[0];
g.inner.appendChild(g.dom);
switch (g.opts.direction) {
case "top":
g.top = "0";
g.left = "0";
g.width = "100%";
g.height = g.opts.distance;
g.translate = "0,-100%,0";
break;
case "bottom":
g.bottom = "0";
g.left = "0";
g.width = "100%";
g.height = g.opts.distance;
g.translate = "0,100%,0";
break;
case "right":
g.top = "0";
g.right = "0";
g.width = g.opts.distance;
g.height = document.documentElement.clientHeight + "px";
g.translate = "100%,0,0";
break;
default:
g.top = "0";
g.left = "0";
g.width = g.opts.distance;
g.height = document.documentElement.clientHeight + "px";
g.translate = "-100%,0,0"
}
g.wrap.style.display = "none";
g.wrap.style.position = (g.target === "body" ? "fixed" : "absolute");
g.wrap.style.top = "0";
g.wrap.style.left = "0";
g.wrap.style.width = "100%";
g.wrap.style.height = "100%";
g.wrap.style.zIndex = 9999999;
g.inner.style.position = "absolute";
g.inner.style.top = g.top;
g.inner.style.bottom = g.bottom;
g.inner.style.left = g.left;
g.inner.style.right = g.right;
g.inner.style.width = g.width;
g.inner.style.height = (g.target === "body" ? g.height : "100%");
g.inner.style.backgroundColor = "#fff";
g.inner.style.transform = "translate3d(" + g.translate + ")";
g.inner.style.webkitTransition = "all .2s ease-out";
g.inner.style.transition = "all .2s ease-out";
g.inner.style.zIndex = 10000000;
g.mask.style.width = "100%";
g.mask.style.height = "100%";
g.mask.style.opacity = "0.1";
g.mask.style.backgroundColor = "black";
g.mask.style.zIndex = "9999998";
g.mask.style.webkitBackfaceVisibility = "hidden";
g.events()
},
open: function () {
var d = this;
d.wrap.style.display = "block";
setTimeout(function () {
d.inner.style.transform = "translate3d(0,0,0)";
d.inner.style.webkitTransform = "translate3d(0,0,0)";
d.mask.style.opacity = 0.1
}, 30);
if (d.opts.time) {
d.timer = setTimeout(function () {
d.close()
}, d.opts.time)
}
},
close: function () {
var d = this;
d.timer && clearTimeout(d.timer);
d.inner.style.webkitTransform = "translate3d(" + d.translate + ")";
d.inner.style.transform = "translate3d(" + d.translate + ")";
d.mask.style.opacity = 0;
setTimeout(function () {
d.wrap.style.display = "none";
d.timer = null;
d.opts.callback && d.opts.callback()
}, 300)
},
events: function () {
var d = this;
d.addEvent(d.mask, "touchmove", function (f) {
f.preventDefault()
});
d.addEvent(d.mask, (d.isMobile() ? "touchend" : "click"), function (f) {
if (d.opts.maskClose) {
d.close()
}
})
}
};
b.mSlider = a
})(window);