/******* * 已解决滑动穿透 * 对于每一个遮罩创建一个实例,遮罩之间互不影响,通过id创建 * 使用js在头部插入必要的样式 * * author:fogwind 2021-09-07 * ********/ var overlayManager = { OVERLAY_ROOT_CLASS: "overlay-root", globalZindex: 1000000, overlayRootDom: null, animationDuration: 0.3, env: null, isInit: false, isCssInit: false, eventListenerOption: { passive: false }, get zIndex() { return this.globalZindex++; }, overlayArr: [], key: 0, get flagKey() { return this.key++; }, overlayRootMaps: {}, init: function(overlayMaskFatherDom) { var self = this; /** * 先在overlayMaskFatherDom下查找是否之前已经插入过遮罩元素,有则跳过初始化;没有则再次初始化 */ var res = this.initOverlayRoot(overlayMaskFatherDom); if(!this.overlayRootMaps[res.id]) { this.overlayRootMaps[res.id] = res.overlayRootDom; this.env = this.detectOS(); this.eventListenerOption = this.getEventListenerOptions(this.eventListenerOption); } }, initCss: function() { if(!this.isCssInit) { this.appendOverlayCss(); this.appendToastCss(); this.isCssInit = true; } }, show: function(overlayInstanceParam) { var overlayInstance = overlayInstanceParam || {zIndex:this.globalZindex}; var overlayRootDom = document.getElementById( this.getOverlayRootId(overlayInstance.overlayMaskFatherDom || document.body) ); this.removeClass(overlayRootDom, 'hide'); this.addClass(overlayRootDom, 'show'); // console.log(overlayRootDom,overlayInstance.rootMaskTransparent); if(overlayInstance.rootMaskTransparent) { this.addClass(overlayRootDom, 'transparent'); } overlayRootDom.style.display = 'block'; overlayRootDom.style.zIndex = overlayInstance.zIndex; // 处理滑动穿透问题 if(this.env.android) { this.setOverflowHidden('add'); } else if(this.env.ios) { var hasAddEvent = false; for(var i = 0; i < this.overlayArr.length; i++) { if(overlayRootDom.id === this.getOverlayRootId(this.overlayArr[i].overlayMaskFatherDom)) { var hasAddEvent = true; } } // 避免重复注册事件 if(!hasAddEvent) { overlayRootDom.addEventListener('touchmove',this.preventEventDefault,this.eventListenerOption); } } this.overlayArr.push(overlayInstance); }, // id -- OverlayGenerator 实例的 __id close: function(callback,id) { var self = this; var overlayRootDom = null; // var preLastOverlayInstance = this.overlayArr.pop(); var sliceIndex, preLastOverlayInstance; this.overlayArr.forEach(function(item,index) { if(id === item.__id) { sliceIndex = index; preLastOverlayInstance = item; } }); this.overlayArr.splice(sliceIndex,1); var preLastOverlayRootDom = document.getElementById( this.getOverlayRootId(preLastOverlayInstance.overlayMaskFatherDom || document.body) ); var last = null; var lastOverlayRootDom = null; if(this.overlayArr.length) { last = this.overlayArr[this.overlayArr.length-1]; lastOverlayRootDom = document.getElementById( this.getOverlayRootId(last.overlayMaskFatherDom || document.body) ); } if(preLastOverlayRootDom === lastOverlayRootDom) { lastOverlayRootDom.style.zIndex = last.zIndex; } else { this.removeClass(preLastOverlayRootDom, 'show'); this.addClass(preLastOverlayRootDom, 'hide'); } /**@todo 可以优化为通过监听动画结束事件处理 */ setTimeout(function() { if(preLastOverlayRootDom !== lastOverlayRootDom) { self.removeClass(preLastOverlayRootDom, 'hide'); preLastOverlayRootDom.style.display = 'none'; preLastOverlayRootDom.style.zIndex = -self.globalZindex; if(self.env.android) { self.setOverflowHidden('remove'); } else if(self.env.ios) { preLastOverlayRootDom.removeEventListener('touchmove',self.preventEventDefault,self.eventListenerOption); } } if(lastOverlayRootDom && self.env.android) { self.setOverflowHidden('add'); } if(callback && typeof callback === 'function') { callback(); } }, this.animationDuration * 1000); }, initOverlayRoot: function(overlayMaskFatherDom) { var overlayRootClass = this.OVERLAY_ROOT_CLASS; var overlayRootId = ''; var overlayRootFatherDom = overlayMaskFatherDom; var _overlay_root = overlayRootFatherDom.querySelector('.' + overlayRootClass); if(!_overlay_root || (_overlay_root && _overlay_root.parentNode !== overlayRootFatherDom)) { var className = 'overlay-root_parent' + '_' + this.flagKey; this.addClass(overlayRootFatherDom,className); overlayRootId = className + '__' + overlayRootClass; _overlay_root = document.createElement('div'); _overlay_root.setAttribute('id',overlayRootId); _overlay_root.setAttribute('class',overlayRootClass); overlayRootFatherDom.appendChild(_overlay_root); } else { overlayRootId = this.getOverlayRootId(overlayRootFatherDom); } return { id: overlayRootId, overlayRootDom: _overlay_root } }, getOverlayRootId:function(overlayRootFather) { var reg = /(overlay\-root\_parent\_\d+)/ig; var regRes = reg.exec(overlayRootFather.className); var rootId = ''; if(regRes) { rootId = regRes[1] + '__' + this.OVERLAY_ROOT_CLASS; } //console.log('domId -- ', rootId); return rootId; }, appendOverlayCss: function() { var headDom = document.getElementsByTagName('head')[0]; var overlayStyleDom = null; var styleSheetText = ''; if(!headDom) { console.log('There is no head element. I will create one and append it to html.'); headDom = document.createElement('head'); } overlayStyleDom = document.getElementById('overlay-style-sheet'); if(!overlayStyleDom) { overlayStyleDom = document.createElement('style'); overlayStyleDom.setAttribute('id','overlay-style-sheet'); styleSheetText = '.overlay-overflow-hidden{overflow:hidden !important;}' + '.overlay-root{position: fixed;top: 0;left: 0;opacity: 0;box-sizing:border-box;width:100%;height:100%;z-index: -1000;background-color: rgba(0,0,0,0.8);overflow: hidden;display:none;}' + '.overlay-root.transparent{background-color: rgba(0,0,0,0.7);}' + '.overlay-root.hide{animation:popupHide ' + this.animationDuration + 's ease-in forwards;}' + '.overlay-root.show{animation:popupShow ' + this.animationDuration + 's ease-in forwards;}' + '@keyframes popupShow {0% {opacity: 0;}100% {opacity: 1;}}' + '@keyframes popupHide {0% {opacity: 1;}100% {opacity: 0;}}' ; overlayStyleDom.appendChild(document.createTextNode(styleSheetText)); headDom.appendChild(overlayStyleDom); } }, // 添加toast提示样式 appendToastCss: function() { var headDom = document.getElementsByTagName('head')[0]; var overlayStyleDom = null; var styleSheetText = ''; if(!headDom) { console.log('There is no head element. I will create one and append it to html.'); headDom = document.createElement('head'); } overlayStyleDom = document.getElementById('toast-style-sheet'); if(!overlayStyleDom) { overlayStyleDom = document.createElement('style'); overlayStyleDom.setAttribute('id','toast-style-sheet'); styleSheetText = '.overlay-toast-root{position: fixed;width:100%;height:100%;top:0;left:0;opacity:0;}' // + '.overlay-toast-root.hide{animation:popupHide ' + overlayManager.animationDuration + 's ease-in forwards;}' + '.overlay-toast-root.show{animation:popupShow ' + overlayManager.animationDuration + 's ease-in forwards;}' + '.overlay-toast-inner{position:absolute;top:50%;left:50%;transform:translate3d(-50%,-50%,0);padding: 16px;width: 400px;background: #fff;display: flex;justify-content: space-between;align-items:center;flex-wrap: nowrap;border-radius: 4px;box-shadow: 0 0 30px 0px rgba(0,0,0,0.7);}' + '.overlay-toast-icon{flex: 0 0 auto;font-size:40px;}' + '.overlay-toast-icon .icon{display: none;}' + '.overlay-toast-icon.success .icon-success{ display: inline;}' + '.overlay-toast-icon.warning .icon-warning{ display: inline;}' + '.overlay-toast-icon.error .icon-error{display: inline; }' + '.overlay-toast-close{flex: 0 0 auto;font-size: 20px;}' + '.overlay-toast-content{ flex: 1 1 auto;width: 100%;font-size: 14px;padding: 0 16px;}' // mobile toast start + '.overlay-mobiletoast-inner{box-sizing:border-box;width: 4.8rem;position:fixed;top: 50%;left: 50%;transform: translate3d(-50%,-50%,0);background-color: #000000;padding: .8rem .5333rem;}' + '.overlay-mobiletoast-icon{box-sizing: border-box;width: 100%; display:flex;justify-content: center;align-items: center;}' + '.overlay-mobiletoast-icon .overlay-mobiletoast-icon-item{display:none;font-size:0;}' + '.overlay-mobiletoast-icon.logo .overlay-mobiletoast-icon-logo{display:block;}' + '.overlay-mobiletoast-icon.close .overlay-mobiletoast-icon-close{display:block;}' + '.overlay-mobiletoast-icon.success .overlay-mobiletoast-icon-success{display:block;}' + '.overlay-mobiletoast-icon.warning .overlay-mobiletoast-icon-warning{display:block;}' + '.overlay-mobiletoast-icon.error .overlay-mobiletoast-icon-error{display:block;}' + '.overlay-mobiletoast-icon-logo span{width: 1.3963rem; height: .9205rem;}' + '.overlay-mobiletoast-icon-item .icon{font-size: .64rem;color:#fff;}' + '.overlay-mobiletoast-content{ box-sizing: border-box;width: 100%;margin-top: .4rem;}' + '.overlay-mobiletoast-content p{font-size: .3733rem;line-height: .64rem;text-align: center;font-weight: 400;color:#fff;}' // mobile toast end // pc toast start + '.overlay-pctoast-inner{box-sizing: border-box;position: absolute;top: 50%;left:50%;transform: translate3d(-50%,-50%,0);width: 180px;min-height: 180px;padding: 30px 20px;background-color: #000;}' + '.overlay-pctoast-content{text-align: center;font-size: 14px;font-weight: 400;line-height: 20px;margin-top: 20px;color: #fff;}.overlay-pctoast-content p{color: #fff;}' + '.overlay-pctoast-icon{display:flex;justify-content: center;}' + '.overlay-pctoast-icon .overlay-pctoast-icon-item{width: 24px;height: 24px;display:none;}' + '.overlay-pctoast-icon .overlay-pctoast-icon-item .icon{display: block;width: 100%;height: 100%;}' + '.overlay-pctoast-icon.error .overlay-pctoast-icon-error,' + '.overlay-pctoast-icon.close .overlay-pctoast-icon-close,' + '.overlay-pctoast-icon.success .overlay-pctoast-icon-success,' + '.overlay-pctoast-icon.warning .overlay-pctoast-icon-warning{display:block;color:#fff;}' // pc toast end + '.overlay-loading-box{position:absolute;top:50%;left:50%;transform:translate3d(-50%,-50%,0);width: 140px;height: 140px;border-radius: 4px;background-color: rgba(0,0,0,0.5);display: flex;align-items: center;justify-content: center;}' + '.overlay-loading-box .circular {height: 50px; width: 50px;animation: loading-rotate 2s linear infinite;}' + '.overlay-loading-box .circular .path {animation: loading-dash 1.5s ease-in-out infinite;stroke-dasharray: 90,150;stroke-dashoffset: 0; stroke-width: 2;stroke: #ffffff;stroke-linecap: round;}' + '@media only screen and (max-width: 640px) {' + '.overlay-toast-inner{ width: 80%; }' + '}' + '@keyframes loading-rotate {to {transform: rotate(1turn)}}' + '@keyframes loading-dash {0% {stroke-dasharray: 1,200;stroke-dashoffset: 0}50% {stroke-dasharray: 90,150;stroke-dashoffset: -40px}to {stroke-dasharray: 90,150;stroke-dashoffset: -120px}}'; overlayStyleDom.appendChild(document.createTextNode(styleSheetText)); headDom.appendChild(overlayStyleDom); } }, // 给元素添加/移除overflowhidden setOverflowHidden: function(flag,dom) { var e = dom || document.body; if(flag === 'add') { this.addClass(e,'overlay-overflow-hidden'); } else if(flag === 'remove') { this.removeClass(e,'overlay-overflow-hidden'); } }, preventEventDefault: function(e) { e.preventDefault(); }, // 检查元素是否是滚动元素 checkScrollElement: function(dom) { var overflowRegExp = /scroll|auto/i; var overflowValue = window.getComputedStyle(dom).overflowY; return overflowRegExp.test(overflowValue); }, // 获取滚动元素 getScrollDom: function(dom) { var overflowRegExp = /scroll|auto/i; for (var e = dom; e && "HTML" !== e.tagName && 1 === e.nodeType; ) { var overflowValue = window.getComputedStyle(e).overflowY; if (overflowRegExp.test(overflowValue)) { return e; } e = e.parentNode; } }, // 判断环境 detectOS: function(ua) { ua = ua || navigator.userAgent; var ipad = /(iPad).*OS\s([\d_]+)/.test(ua); var iphone = !ipad && /(iPhone\sOS)\s([\d_]+)/.test(ua); var android = /(Android);?[\s/]+([\d.]+)?/.test(ua); var ios = iphone || ipad; var isMobile = !!window.navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|IEMobile|MQQBrowser|JUC|Windows Phone)/i); return { isMobile: isMobile, ios: ios, android: android }; }, // 添加类名 addClass: function (dom, str) { var oriClassName = dom.className ? dom.className.trim() : ''; if((oriClassName && oriClassName.indexOf(str) < 0) || !oriClassName) { dom.className = oriClassName ? (oriClassName + ' ' + str) : str; } }, // 删除类名 removeClass: function (dom, str) { var oriClassName = dom.className ? dom.className.trim() : ''; if(oriClassName && oriClassName.indexOf(str) >= 0) { dom.className = oriClassName.replace(str,'').replace(/\s{2,}/g, ' ').trim(); } }, // 替换类名 replaceClass: function (dom, oriStr, toStr) { var oriClassName = dom.className ? dom.className.trim() : ''; if(oriClassName && oriClassName.indexOf(oriStr) >= 0) { dom.className = oriClassName.replace(oriStr,toStr); } else { dom.className = oriClassName ? (oriClassName + ' ' + toStr) : toStr; } }, // 检测是否支持passive getEventListenerOptions: function(options) { if (!options) { throw new Error('options must be provided'); } var isSupportOptions = false; var listenerOptions = { get passive() { isSupportOptions = true; return; } }; /* istanbul ignore next */ var noop = function noop() {}; var testEvent = '__TUA_BSL_TEST_PASSIVE__'; window.addEventListener(testEvent, noop, listenerOptions); window.removeEventListener(testEvent, noop, listenerOptions); var capture = options.capture; /* istanbul ignore next */ return isSupportOptions ? options : typeof capture !== 'undefined' ? capture : false; }, // 判断一个变量是不是元素节点 isHtmlNode: function(obj) { var d = document.createElement("div"); try{ d.appendChild(obj.cloneNode()); return obj.nodeType==1 ? true : false; }catch(e){ return false; } } }; overlayManager.initCss(); function OverlayGenerator (options) { if(!options) { throw new Error('options must be required!'); } this.__id = this._getId(); // 可以是dom对象或者字符串(字符串表示元素id) // this.overlayMaskFatherDom 把overlay-root元素插入到的元素 if(options.overlayMaskFatherDom && Object.prototype.toString.call(options.overlayMaskFatherDom) === "[object String]") { this.overlayMaskFatherDom = document.getElementById(options.overlayMaskFatherDom) || document.body; } else if(overlayManager.isHtmlNode(options.overlayMaskFatherDom)) { this.overlayMaskFatherDom = options.overlayMaskFatherDom; } else { this.overlayMaskFatherDom = document.body; } this.animationDerection = options.animationDerection || 'slide-up'; // 默认动画效果 // 向后兼容 this.innerContainerDomId = options.innerContainerDomId || options.innerContainerDom || null; if(!this.innerContainerDomId) { throw new Error('innerContainerDomId or innerContainerDom must be required!'); } this.rootMaskTransparent = !!options.rootMaskTransparent; this.zIndex = null; // 向后兼容 this.innerScrollDomId = options.innerScrollDomId || options.innerScrollDom || this.innerContainerDomId; this.innerContainerDom = null; this.innerContainerDomOriginalTransform = null; // 保存弹窗元素transform最初的值,关闭弹窗时要重置为最初的值 this.innerContainerDomComputeStyle = null; /** * @todo innerScrollDom 只考虑了只有一个可滚动元素的情况,wk分类导航弹窗里有两个可滚动元素 */ this.innerScrollDom = null; this.animationDuration = options.animationDuration || overlayManager.animationDuration; this.env = null; this.touchStartPoint = null; this.innerScrollTouchStartHandler = null; this.innerScrollTouchMoveHandler = null; this.closeCallback = null; if(overlayManager.isHtmlNode(this.innerContainerDomId)) { this.innerContainerDom = this.innerContainerDomId; } else { this.innerContainerDom = document.getElementById(this.innerContainerDomId); } if(overlayManager.isHtmlNode(this.innerScrollDomId)) { this.innerScrollDom = this.innerScrollDomId; } else { this.innerScrollDom = document.getElementById(this.innerScrollDomId); } this.init(); } OverlayGenerator.prototype = { constructor: OverlayGenerator, init: function () { overlayManager.init(this.overlayMaskFatherDom); this.innerContainerDomComputeStyle = window.getComputedStyle(this.innerContainerDom,null); // console.log(this.innerContainerDomComputeStyle.transform); // console.log(this.innerContainerDomComputeStyle.display); this.env = overlayManager.env; this.zIndex = null; }, // 生成模拟id _getId: function() { var s = '0123456789abcdefghijklmnopqrstuvwxyz'; // charCodeAt var temp = +new Date(); var randomNum = Math.floor(Math.random() * s.length); return temp + s.charCodeAt(randomNum); }, // 显示遮罩 show: function (callback) { if(!this.zIndex) { this.zIndex = overlayManager.zIndex; } overlayManager.show(this); this.innerContainerDom.style.display = this.innerContainerDom.getAttribute('data-display') || 'block'; this.innerContainerDom.style.zIndex = this.zIndex + 1; // console.log(this.innerContainerDomComputeStyle.transform); // 元素只有显示在页面上getComputedStyle方法才能获取到有效值 if(!this.innerContainerDomOriginalTransform) { this.innerContainerDomOriginalTransform = this.innerContainerDomComputeStyle.transform; // console.log(this.innerContainerDomOriginalTransform); if(this.innerContainerDomOriginalTransform === 'none') { this.innerContainerDomOriginalTransform = 'matrix(1, 0, 0, 1, 0, 0)'; } } /* 现在使用transition添加动画效果 */ this.setTransitionAnimateShow(); // 处理滑动穿透问题 // console.log('env --- ',this.env.ios); if(this.env.ios) { this.innerScrollTouchStartHandler = this.innerTouchStartHandler.bind(this); this.innerScrollTouchMoveHandler = this.innerTouchmoveHandler.bind(this); this.innerScrollDom.addEventListener('touchstart',this.innerScrollTouchStartHandler); this.innerScrollDom.addEventListener('touchmove',this.innerScrollTouchMoveHandler); } if(callback && typeof callback === 'function') { setTimeout(function() { callback(); },this.animationDuration * 1000); } }, // 关闭遮罩 close: function (callback) { this.setTransitionAnimateClose(); overlayManager.close(this.animateEndCallback.bind(this,callback),this.__id); }, /** * 矩阵变换 * https://zhuanlan.zhihu.com/p/92883312 */ setTransitionAnimateShow: function() { var _this = this; var transformStr = this.innerContainerDomComputeStyle.transform; var innerContainerSize = this.innerContainerDom.getBoundingClientRect(); var matrix = []; var x = 0; // 最初x方向的偏移量 var y = 0; // 最初y方向的偏移量 var initTransformValue = ''; this.innerContainerDom.style.transitionProperty = 'transform, opacity'; this.innerContainerDom.style.opacity = '0'; this.innerContainerDom.style.transitionDuration = '0s'; // 从矩阵函数字符串中解析出矩阵函数名字和矩阵 if(!transformStr || transformStr === 'none') { x = 0; y = 0; } else { // 下面三行代码来自BetterScroll core.js matrix = transformStr.split(')')[0].split(', '); x = +(matrix[12] || matrix[4]) || 0; y = +(matrix[13] || matrix[5]) || 0; } if(this.animationDerection === 'slide-up') { // 如果动画效果是向上滑出,那么通过transform修改元素的初始位置(向下偏移一个元素高度或者y) initTransformValue = 'matrix(1, 0, 0, 1, ' + x + ', ' + (y ? (y + (-y/Math.abs(y)) * (-y)) : innerContainerSize.height) + ')'; } if(this.animationDerection === 'slide-down') { initTransformValue = 'matrix(1, 0, 0, 1, ' + x + ', ' + (y ? -(y + (-y/Math.abs(y)) * (-y)) : -innerContainerSize.height) + ')'; } if(this.animationDerection === 'slide-right') { // 如果动画效果是向上滑出,那么通过transform修改元素的初始位置(向下偏移一个元素高度或者y) initTransformValue = 'matrix(1, 0, 0, 1, ' + (x ? (x + (-x/Math.abs(x)) * (-x)) : innerContainerSize.width) + ', ' + y + ')'; } if(this.animationDerection === 'slide-left') { initTransformValue = 'matrix(1, 0, 0, 1, ' + (x ? -(x + (-x/Math.abs(x)) * (-x)) : -innerContainerSize.width) + ', ' + y + ')'; } // console.log(x,y,initTransformValue); this.innerContainerDom.style.transform = initTransformValue; setTimeout(function() { _this.innerContainerDom.style.transitionDuration = _this.animationDuration + 's'; _this.innerContainerDom.style.transform = 'matrix(1, 0, 0, 1, ' + x + ', ' + y + ')'; _this.innerContainerDom.style.opacity = '1'; },0); }, setTransitionAnimateClose: function() { var currentTransform = this.innerContainerDomComputeStyle.transform; var innerContainerSize = this.innerContainerDom.getBoundingClientRect(); var matrix = currentTransform.split(')')[0].split(', '); var x = +(matrix[12] || matrix[4]) || 0; var y = +(matrix[13] || matrix[5]) || 0; if(this.animationDerection === 'slide-up') { this.innerContainerDom.style.transform = 'matrix(1, 0, 0, 1, ' + x + ', ' + (y ? (y + (-y/Math.abs(y)) * (-y)) : innerContainerSize.height) + ')'; } if(this.animationDerection === 'slide-down') { this.innerContainerDom.style.transform = 'matrix(1, 0, 0, 1, ' + x + ', ' + (y ? -(y + (-y/Math.abs(y)) * (-y)) : -innerContainerSize.height) + ')'; } if(this.animationDerection === 'slide-right') { this.innerContainerDom.style.transform = 'matrix(1, 0, 0, 1, ' + (x ? (x + (-x/Math.abs(x)) * (-x)) : innerContainerSize.height) + ', ' + y + ')'; } if(this.animationDerection === 'slide-left') { this.innerContainerDom.style.transform = 'matrix(1, 0, 0, 1, ' + (x ? -(x + (-x/Math.abs(x)) * (-x)) : -innerContainerSize.height) + ', ' + y + ')'; } // console.log(this.innerContainerDom.style.transform); this.innerContainerDom.style.opacity = '0'; }, // 动画结束回调 animateEndCallback: function(callback) { this.innerContainerDom.style.display = 'none'; this.innerContainerDom.style.transform = this.innerContainerDomOriginalTransform; if(this.env.ios) { if(this.innerScrollTouchStartHandler) { this.innerScrollDom.removeEventListener('touchstart',this.innerScrollTouchStartHandler); this.innerScrollTouchStartHandler = null; } if(this.innerScrollTouchMoveHandler) { this.innerScrollDom.removeEventListener('touchmove',this.innerScrollTouchMoveHandler); this.innerScrollTouchMoveHandler = null; } } if(callback && typeof callback === 'function') { callback(); } }, // innerTouchmoveHandler: function(e) { var touchEndPoint = e.targetTouches[0]; var moveOffsetY = touchEndPoint.screenY - this.touchStartPoint.screenY; // 滚动到顶部 if(moveOffsetY > 0 && this.innerScrollDom.scrollTop === 0) { e.preventDefault(); return; } // 滚动到底部 if(moveOffsetY < 0 && (this.innerScrollDom.scrollTop + this.innerScrollDom.clientHeight >= this.innerScrollDom.scrollHeight)) { e.preventDefault(); return; } // console.log(this.innerScrollDom.scrollTop+'--'+this.innerScrollDom.clientHeight+'--'+this.innerScrollDom.scrollHeight); }, innerTouchStartHandler: function(e) { this.touchStartPoint = e.targetTouches[0]; }, }; // 交互弹窗 var OverlayToast = { rootDomId: 'overlay_toast_root', rootDom: null, // 移动端改版 toastMobilHtml: '
', // 最初版本 toastHtml: ' ', // pc改版 toastPcHtml: ' ', loadingHtml: ' ', customerToast: function(customerHtmlStr) { this.initRootDom(customerHtmlStr); }, toast: function(msg,icon,callback) { var msgContent = msg; var osEnv = overlayManager.detectOS(); var rootDom, toastHtmlStr; var closeDomClass; var typeString = Object.prototype.toString.call(msg); if( typeString === '[object String]') { msgContent = '' + msg + '
'; } else if(typeString === '[object Array]') { msgContent = msg.map(function(str) { return '' + str + '
'; }).join(''); } // isMobile if(osEnv.isMobile) { toastHtmlStr = this.toastMobilHtml.replace('{{msg}}',msgContent); closeDomClass = '.overlay-mobiletoast-icon-'+ icon + '.overlay-mobiletoast-close'; } else { closeDomClass = '.overlay-pctoast-icon-'+ icon + '.overlay-pctoast-close'; toastHtmlStr = this.toastPcHtml.replace('{{msg}}',msgContent); } toastHtmlStr = toastHtmlStr.replace('{{iconType}}',icon); rootDom = this.initRootDom(toastHtmlStr); //@todo close error 不自动关闭;其他的自动关闭 if(icon === 'close' || icon === 'error') { rootDom.querySelector(closeDomClass).addEventListener('click',function(e) { // if(osEnv.isMobile) { // OverlayToast.close(); // } else { // OverlayToast.close(); // } OverlayToast.close(); callback && callback(); }); } else { setTimeout(function() { OverlayToast.close(); callback && callback(); },1500); } }, loading: function() { this.initRootDom(this.loadingHtml); }, close: function() { var that = this; if(this.rootDom && this.rootDom.style.display === 'block') { // document.body.removeChild(this.rootDom); overlayManager.removeClass(this.rootDom,'show'); overlayManager.addClass(this.rootDom,'hide'); setTimeout(function() { that.rootDom.innerHTML = ''; that.rootDom.style.display = 'none'; },overlayManager.animationDuration * 1000); } }, initRootDom: function(str) { var rootDom = document.getElementById('overlay_toast_root'); if(!rootDom) { rootDom = document.createElement('div'); rootDom.setAttribute('id', this.rootDomId); rootDom.setAttribute('class', 'overlay-toast-root'); document.body.appendChild(rootDom); } rootDom.style.display = 'block'; rootDom.style.zIndex = overlayManager.zIndex; rootDom.innerHTML = str; this.rootDom = rootDom; overlayManager.removeClass(this.rootDom,'hide'); overlayManager.addClass(this.rootDom,'show'); return rootDom; } }; /* 把字符串添加到剪切板 https://github.com/zenorocha/clipboard.js */ var CopyTextPlugin = { copyText: function(val,callback) { var res = this.fakeCopyAction(val); if(!callback) { if(res.isSuccess) { OverlayToast.toast('Copy Successfully!', 'success'); } else { OverlayToast.toast('Copy Failed! Text: ' + val + '', 'warning'); } setTimeout(function() { OverlayToast.close(); },1500); } else { callback(res); } }, createFakeElement: function (value) { var isRTL = document.documentElement.getAttribute('dir') === 'rtl'; var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS fakeElement.style.fontSize = '12pt'; // Reset box model fakeElement.style.border = '0'; fakeElement.style.padding = '0'; fakeElement.style.margin = '0'; // Move element out of screen horizontally fakeElement.style.position = 'absolute'; fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically var yPosition = window.pageYOffset || document.documentElement.scrollTop; fakeElement.style.top = "".concat(yPosition, "px"); fakeElement.setAttribute('readonly', ''); fakeElement.value = value; return fakeElement; }, fakeCopyAction: function (value) { var selectedText; var isCopySuccess; var fakeElement = this.createFakeElement(value); document.body.appendChild(fakeElement); fakeElement.select(); fakeElement.setSelectionRange(0, fakeElement.value.length); selectedText = fakeElement.value; isCopySuccess = this.command('copy'); fakeElement.remove(); return { isSuccess: isCopySuccess, selectedText: selectedText } }, command: function (type) { try { return document.execCommand(type); } catch (err) { return false; } } }; // 节流函数 function throttle(fun,t,mustRun,denyLast) { var timer = null; var startTime = 0; return function(event) { var that = this, args = arguments; clearTimeout(timer); var later = function() { timer = null; if(denyLast) fun.apply(that,args); // console.log('执行的是later.'); }; var currTime = new Date().getTime(); if(currTime - startTime >= mustRun) { // console.log(currTime - startTime); fun.apply(that,args); startTime = currTime; } else { timer = setTimeout(later,t); } }; } // 防抖函数 function debounce(fun,t,immediate) { var timeout; //返回真正的scroll事件的事件处理程序 return function(event) { var that = this, arg = arguments; var later = function() { timeout = null; if(!immediate) fun.apply(that,arguments); }; var callNow = immediate && !timeout;//这一句位置很重要 clearTimeout(timeout); timeout = setTimeout(later,t); if(callNow) { fun.apply(that,arguments); } } }; //浮点数加法运算 function FloatAdd(arg1,arg2){ var r1,r2,m; try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0} try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0} m=Math.pow(10,Math.max(r1,r2)); return (arg1*m+arg2*m)/m; } //浮点数减法运算 function FloatSub(arg1,arg2){ var r1,r2,m,n; try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0} try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0} m=Math.pow(10,Math.max(r1,r2)); //动态控制精度长度 // n=(r1=r2)?r1:r2; n = Math.max(r1,r2); return ((arg1*m-arg2*m)/m).toFixed(n); } //浮点数乘法运算 function FloatMul(arg1,arg2) { var m=0,s1=arg1.toString(),s2=arg2.toString(); try{m+=s1.split(".")[1].length}catch(e){} try{m+=s2.split(".")[1].length}catch(e){} return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m); } //浮点数除法运算 function FloatDiv(arg1,arg2){ var t1=0,t2=0,r1,r2; try{t1=arg1.toString().split(".")[1].length}catch(e){} try{t2=arg2.toString().split(".")[1].length}catch(e){} with(Math){ r1=Number(arg1.toString().replace(".","")); r2=Number(arg2.toString().replace(".","")); return (r1/r2)*pow(10,t2-t1); } } console.log('overlay.js load complate ');