'use strict';
/* 钱香弹出层 */
/**
* @module qianxiang_h5.layer
* @description 请使用whale.layer模块内调用
*/
import * as utils from '../lib/utils';
import * as os from '../lib/os';
import { ready } from '../lib/dom';
const _pre = 'myui-';
let layerIdx = -1;
function classWrap(str) {
return _pre + str;
}
const clickHandlePool = {// 委托事件池子
pool: {},
disPatchClick: function (idx) {
if (utils.isFunction(this.pool[idx])) {
this.pool[idx]();
}
},
regisHandle: function (idx, func) {
this.pool[idx] = func;
},
removeHandle: function (idx) {
this.pool[idx] = null;
},
removeHandleByGroup: function (group) {
for (let i in this.pool) {
if (group == i[0]) {
this.pool[i] = null;
}
}
}
};
/**
* 关闭弹层
* @param {Number|Object} idxOrDom 要关闭的弹层dom或者对应idx
* @example
* layer.close(1);
*/
function close(idxOrDom) {
let layer = null;
let layerIdex = -1;
if (typeof idxOrDom == 'number') {
layerIdex = idxOrDom;
layer = document.getElementById(classWrap('layer') + idxOrDom);
} else {
layer = idxOrDom;
layerIdex = layer.getAttribute('index');
}
if (layer) {
// 干掉事件委托
clickHandlePool.removeHandleByGroup(layerIdex);
layer.style.display = 'none';
setTimeout(function () {
layer.remove();
}, 200);
}
}
//ios 不支持window document body的click委托
ready(function () {
document.body.addEventListener((os.ios || os.android) ? 'touchend' : 'click', function (ev) {
let target = ev.target,
anch = target;
if (target.className.indexOf(_pre) < 0) {
return;
}
//找到祖先元素
while (anch) {
if (anch.classList.contains(classWrap('layer'))) {
break;
}
anch = anch.parentNode;
}
if (target.classList.contains(classWrap('close'))) {
if (anch && anch != document) {
ev.stopPropagation();
ev.preventDefault();
close(anch);
return false;
}
} else if (target.classList.contains(classWrap('btn'))) {
ev.stopPropagation();
ev.preventDefault();
let handle = target.getAttribute('eventhandle');
if (handle) {
clickHandlePool.disPatchClick(handle);
}
}
});
});
function createDomWithConf(tagName, conf, content) {
let dom = document.createElement(tagName);
if (typeof conf == 'object') {
for (let it in conf) {
let fillValue = conf[it];
switch (it) {
case 'class':
if (!(fillValue instanceof Array)) {
fillValue = [fillValue];
}
fillValue = fillValue.map(function (a) {
return _pre + a;
}).join(' ');
break;
case 'id':
fillValue = classWrap(fillValue);
}
dom.setAttribute(it, fillValue);
}
}
dom.innerHTML = content === undefined ? '' : content;
return dom;
}
function createBase(withMask = false) {
layerIdx++;
let root = createDomWithConf('div', {
'index': layerIdx,
'class': 'layer',
'id': 'layer' + layerIdx
});
document.body.appendChild(root);
let mainWrap = createDomWithConf('div', {
'class': 'main'
});
let main = createDomWithConf('div', {
'class': 'section'
});
if (withMask === true) {
root.appendChild(createDomWithConf('div', {'class': 'mask'}));
}
root.appendChild(mainWrap);
mainWrap.appendChild(main);
return main;
}
function createMsgBox(title, content, sureOrCancelText, sureOrCancelFunc, sureText, sureFunc) {
let box = createDomWithConf('div', {
'class': ['child', 'msgbox', 'anim-scale']
});
let titleDom = createDomWithConf('h3', null, title);
let contentDom = createDomWithConf('div', {
'class': 'content'
}, content);
let btnsWrap = createDomWithConf('span', {
'class': 'btns-wrap'
});
let evHandle = layerIdx + '_0';
let leftBtn = createDomWithConf('span', {
'class': ['btn', 'btn0', sureText === undefined ? 'btn-sure' : 'btn-cancel'],
'eventHandle': evHandle
}, sureOrCancelText);
let keepLayerIdx = layerIdx;
clickHandlePool.regisHandle(evHandle, function () {
if (utils.isFunction(sureOrCancelFunc)) {
let ret = sureOrCancelFunc();
if (ret !== false) {
close(keepLayerIdx);
}
} else {
close(keepLayerIdx);
}
});
let rightBtn = null;
if (sureText != undefined) {
let evHandleSure = layerIdx + '_1';
rightBtn = createDomWithConf('span', {
'class': ['btn', 'btn1', 'btn-sure'],
'eventHandle': evHandleSure
}, sureText);
clickHandlePool.regisHandle(evHandleSure, function () {
if (utils.isFunction(sureFunc)) {
let ret = sureFunc();
if (ret !== false) {
close(keepLayerIdx);
}
} else {
close(keepLayerIdx);
}
});
}
box.appendChild(titleDom);
box.appendChild(contentDom);
box.appendChild(btnsWrap);
btnsWrap.appendChild(leftBtn);
rightBtn && btnsWrap.appendChild(rightBtn);
return box;
}
/**
* 显示MessageBox
* @param {String} title 标题
* @param {String} content 内容
* @param {String} sureOrCancelText 确定或者取消按钮
* @param {Function} sureOrCancelFunc 确定或者取消按钮的回调
* @param {String} sureText 确定按钮
* @param {Function} sureFunc 确定按钮回调
* @example
* layer.showMsgBox('温馨提示','确定删除吗','确定', null, '取消', null);
* layer.showMsgBox('温馨提示','确定删除吗','确定', function(){});
*/
function showMsgBox(title, content, sureOrCancelText, sureOrCancelFunc, sureText, sureFunc) {
close(layerIdx);
let base = createBase(true);
let box = createMsgBox(title, content, sureOrCancelText, sureOrCancelFunc, sureText, sureFunc);
base.appendChild(box);
return layerIdx;
}
let waitingLayerIdx = null;
/**
* 显示加载层
* @param {String} text 加载文字
* @example
* layer.showLoading('正在加载');
*/
function showLoading (text) {
close(layerIdx);
let base = createBase(true);
let loading = createDomWithConf('div', {
'class': ['child', 'waiting', 'anim-scale']
});
let sniper = createDomWithConf('div', {
'class': ['sniper']
});
let textDom = createDomWithConf('div', {
'class': ['sniper-text']
}, text);
loading.appendChild(sniper);
loading.appendChild(textDom);
base.appendChild(loading);
waitingLayerIdx = layerIdx;
}
/**
* 关闭加载层, 和layer.showLoading配套使用
*/
function closeLoading() {
close(waitingLayerIdx);
}
/**
* 弹出Toast(从中间弹出)
* @param {String} content 提示内容
* @param {Number} delay 显示时间(秒), 只能传递3-5之内的数字
* @param {String} style 附加样式
* @example
* //一个参数
* layer.showToast2('通知成功');
* //2个参数
* layer.showToast2('通知成功',3);
*/
function showToast(content, delay, style) {
delay = Math.min(Number(delay) || 3, 5);
let base = createBase(false);
let tips = createDomWithConf('div', {
'class': ['child', 'msg', 'msg-pop', 'anim-scale'],
'style': style
}, content);
base.appendChild(tips);
(function (_) {
setTimeout(function () {
close(_);
}, delay * 1000);
})(layerIdx);
return layerIdx;
}
/**
* 弹出Toast(从底部弹出)
* @param {String} content 提示内容
* @param {Number} delay 显示时间(秒), 只能传递3-5之内的数字
* @param {String} style 附加样式
* @example
* //一个参数
* layer.showToast2('通知成功');
* //2个参数
* layer.showToast2('通知成功',3);
*/
function showToast2(content, delay = 3, style = '') {
delay = Math.min(Number(delay) || 3, 5);
let base = createBase(false);
let tips = createDomWithConf('div', {
'class': ['child', 'msg', 'msg-slide', 'anim-up'],
'style': style
}, content);
base.appendChild(tips);
(function (_) {
setTimeout(function () {
close(_);
}, delay * 1000);
})(layerIdx);
return layerIdx;
}
/**
* 弹出弹层
* @param {Object} config 配置
* @property {String} config.content 弹出层的innerHTML
* @property {String} config.sel 弹出层选择器
* @example
* //使用选择器弹出
* layer.open({
* sel: '#poplayer'
* });
* //传入content参数
* layer.open({
* content: '<div class="poplayer">我是弹层</div>'
* });
*/
function open(config) {
if (typeof config != 'object' || (config.content == undefined && config.sel == undefined)) {
return;
}
let contentHTML = '';
if (config.content) {
contentHTML = config.content;
} else {
let dom = document.querySelector(config.sel);
dom && (contentHTML = dom.innerHTML);
}
// close(layerIdx);
let base = createBase(true);
let div = createDomWithConf('div', {
'class': ['child', 'anim-scale']
}, contentHTML);
base.appendChild(div);
return layerIdx;
}
export {
close,
showMsgBox,
showLoading,
closeLoading,
showToast,
showToast2,
open
};