first commit
This commit is contained in:
420
public/component/pear/module/drawer.js
Executable file
420
public/component/pear/module/drawer.js
Executable file
@ -0,0 +1,420 @@
|
||||
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);
|
Reference in New Issue
Block a user