| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420 |
- 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);
|