window.afterClickBack = function () { console.log('afterClickBack', location.href) } var vTools = { // 公共前缀url baseUrl: '', errorCodeMap: { 1001: '需要重新登录', 1002: '缺失参数', 1003: '没有权限', }, $env: {}, // 传入你要获取的参数的名字 getParam: function (name) { var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i'); var r = window.location.search.substr(1).match(reg); //获取url中'?'符后的字符串并正则匹配 var context = ''; if (r != null) context = r[2]; // 释放变量 reg = null; r = null; return context == null || context == '' || context == 'undefined' ? '' : context; }, // 数组对象根据某一个值进行冒泡排序 // arr 数组 // value 字符串 bSort: function (arr, value) { var len = arr.length; for (var i = 0; i < len - 1; i++) { for (var j = 0; j < len - 1 - i; j++) { // 相邻元素两两对比,元素交换,大的元素交换到后面 if (arr[j][value] > arr[j + 1][value]) { var temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } return arr; }, // 解决ios返回不刷新页面的问题 iosBackRefresh: function () { var isPageHide = false; window.addEventListener('pageshow', function () { if (isPageHide) { location.reload(); } }); window.addEventListener('pagehide', function () { isPageHide = true; }); }, // 通过userAgent获取用户手机操作系统类型 androidOrIOS: function () { var u = navigator.userAgent.toLowerCase(); var app = navigator.appVersion; var agent = null; if (/iphone|ipod|ipad|ios/.test(u)) { agent = 'ios' } else { agent = 'android' } return agent }, // 取[m, n]随机数 getRandomNumber: function (min, max) { return Math.floor(Math.random() * (max - min + 1) + min); }, // 获取唯一的uuid // https://www.kancloud.cn/ifeng/js100/622666 getRandomUuid: function () { var s = []; var hexDigits = "0123456789abcdef"; for (var i = 0; i < 36; i++) { s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); } s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010 s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01 s[8] = s[13] = s[18] = s[23] = "-"; var uuid = s.join(""); return uuid; }, // 获取随机字符串 // 不传参数则获取长度不固定的字符串 getRandomString: function (len) { var randomString = ''; if (len) { /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/ var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; var maxPos = $chars.length; for (i = 0; i < len; i++) { randomString += $chars.charAt(Math.floor(Math.random() * maxPos)); } } else { // Math.random() 生成随机数字, eg: 0.123456 // .toString(36) 转化成36进制 : "0.4fzyo82mvyr" // .substring(2) 去掉前面两位 : "yo82mvyr" // .slice(-8) 截取最后八位 : "yo82mvyr" randomString = Math.random().toString(36).substring(2) } return randomString; }, // FROM: https://www.jianshu.com/p/90ed8b728975 // 比较两个兑现是否相等 // 返回true为相等,返回false为不相等 deepCompare: function (x, y) { var i, l, leftChain, rightChain; function compare2Objects(x, y) { var p; // remember that NaN === NaN returns false // and isNaN(undefined) returns true if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') { return true; } // Compare primitives and functions. // Check if both arguments link to the same object. // Especially useful on the step where we compare prototypes if (x === y) { return true; } // Works in case when functions are created in constructor. // Comparing dates is a common scenario. Another built-ins? // We can even handle functions passed across iframes if ((typeof x === 'function' && typeof y === 'function') || (x instanceof Date && y instanceof Date) || (x instanceof RegExp && y instanceof RegExp) || (x instanceof String && y instanceof String) || (x instanceof Number && y instanceof Number)) { return x.toString() === y.toString(); } // At last checking prototypes as good as we can if (!(x instanceof Object && y instanceof Object)) { return false; } if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) { return false; } if (x.constructor !== y.constructor) { return false; } if (x.prototype !== y.prototype) { return false; } // Check for infinitive linking loops if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) { return false; } // Quick checking of one object being a subset of another. // todo: cache the structure of arguments[0] for performance for (p in y) { if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { return false; } else if (typeof y[p] !== typeof x[p]) { return false; } } for (p in x) { if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { return false; } else if (typeof y[p] !== typeof x[p]) { return false; } switch (typeof (x[p])) { case 'object': case 'function': leftChain.push(x); rightChain.push(y); if (!compare2Objects(x[p], y[p])) { return false; } leftChain.pop(); rightChain.pop(); break; default: if (x[p] !== y[p]) { return false; } break; } } return true; } if (arguments.length < 1) { return true; //Die silently? Don't know how to handle such case, please help... // throw "Need two or more arguments to compare"; } for (i = 1, l = arguments.length; i < l; i++) { leftChain = []; //Todo: this can be cached rightChain = []; if (!compare2Objects(arguments[0], arguments[i])) { return false; } } return true; }, splitPhone: function (phone) { return String(phone).replace(/\s/g, '').replace(/(?=(\d{4})+$)/g, ' ') }, // https://blog.csdn.net/jacoox/article/details/80719456 // https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/129、https://segmentfault.com/a/1190000012490380 // 防抖: 其中 func 为需要进行防抖操作的函数(如发送联想请求的函数),delay 为延迟时间 debounce: function (func, delay) { var timer = null return function () { var _this = this var _arg = arguments clearTimeout(timer) timer = setTimeout(function () { func.apply(_this, _arg) }, delay) } }, // 节流: 其中 func 为需要进行节流操作的函数,wait为等待时间 throttle: function (func, wait) { var lastTime = 0 return function (e) { var now = +new Date() if (now - lastTime > wait) { func.apply(this, arguments) lastTime = now } } }, isWeiXinBrower: function () { var ua = navigator.userAgent.toLowerCase(); if (ua.match(/MicroMessenger/i) == 'micromessenger') { return true; } else { return false; } }, // 解决 客户端2.9.5 replace失效问题 locationReplace: function (url) { if (history.replaceState) { history.replaceState(null, document.title, url); history.go(0); } else { location.replace(url); } }, iosAppFns: function () { window.JyObjMessage = new Object() window.JyObj = { //清除 JyObjMessage clearMessage: function () { JyObjMessage = new Object(); }, //隐藏显示底部菜单栏 0:隐藏;1:显示 hiddenBottom: function (val) { JyObjMessage["hidden"] = val; window.webkit.messageHandlers.hiddenBottom.postMessage(JyObjMessage); JyObj.clearMessage(); }, //微信登录 loginByWeixin: function () { window.webkit.messageHandlers.loginByWeixin.postMessage(JyObjMessage); JyObj.clearMessage(); }, //分享功能 share: function (type, title, content, link) { JyObjMessage["type"] = type JyObjMessage["title"] = title JyObjMessage["content"] = content JyObjMessage["link"] = link window.webkit.messageHandlers.share.postMessage(JyObjMessage); JyObj.clearMessage(); }, //保存用户token saveUserToken: function (val) { JyObjMessage["token"] = val; window.webkit.messageHandlers.saveUserToken.postMessage(JyObjMessage); JyObj.clearMessage(); }, //获取用户token getUserToken: function () { return JyObj.IosCall("getUserToken") }, //移除用户token removeUserToken: function () { window.webkit.messageHandlers.removeUserToken.postMessage(JyObjMessage); JyObj.clearMessage(); }, //查看开关状态 是否接受消息 checkNoticePermission: function () { return JyObj.IosCall("checkNoticePermission") }, //打开接受消息开关 openSystemNotification: function () { window.webkit.messageHandlers.openSystemNotification.postMessage(JyObjMessage); JyObj.clearMessage(); }, //获取极光推送id getPushRid: function () { return JyObj.IosCall("getPushRid") }, //跳转外部链接 openExternalLink: function (url, title) { JyObjMessage["url"] = url JyObjMessage["title"] = title window.webkit.messageHandlers.openExternalLink.postMessage(JyObjMessage); JyObj.clearMessage(); }, //获取当前版本号 getVersion: function () { return JyObj.IosCall("getVersion") }, alert: function (content) { JyObjMessage["content"] = content window.webkit.messageHandlers.alert.postMessage(JyObjMessage); JyObj.clearMessage(); }, //是否安装了微信 isInstallWeixin: function () { return JyObj.IosCall("isInstallWeixin") }, //登录加密 getCipherText: function (val) { JyObjMessage["phone"] = val return JyObj.IosCall("getCipherText", JyObjMessage) }, //刷新首页和订阅页面 checkLab: function () { window.webkit.messageHandlers.checkLab.postMessage(JyObjMessage); JyObj.clearMessage(); }, //登录成功后向客户端传参 loginSuccess: function (status) { JyObjMessage["status"] = status window.webkit.messageHandlers.loginSuccess.postMessage(JyObjMessage); JyObj.clearMessage(); }, //客户端登录页面点击返回 跳转到搜索首页 backUrl: function (val) { JyObjMessage["status"] = val; window.webkit.messageHandlers.backUrl.postMessage(JyObjMessage); JyObj.clearMessage(); }, //清空通知栏消息 clearPushMessage: function () { window.webkit.messageHandlers.clearPushMessage.postMessage(JyObjMessage); JyObj.clearMessage(); }, //隐藏小红点 hideRedSpotOnMenu: function (menu) { JyObjMessage["menu"] = menu; window.webkit.messageHandlers.hideRedSpotOnMenu.postMessage(JyObjMessage); JyObj.clearMessage(); }, //显示小红点 showRedSpotOnMenu: function (menu) { JyObjMessage["menu"] = menu; window.webkit.messageHandlers.showRedSpotOnMenu.postMessage(JyObjMessage); JyObj.clearMessage(); }, //微信支付 wxPay: function (order) { JyObjMessage["order"] = order; window.webkit.messageHandlers.wxPay.postMessage(JyObjMessage); JyObj.clearMessage(); }, //支付宝支付 aliPay: function (order) { JyObjMessage["order"] = order; window.webkit.messageHandlers.aliPay.postMessage(JyObjMessage); JyObj.clearMessage(); }, //获取原生的推送id getOtherPushRid: function () { return JyObj.IosCall("getOtherPushRid") }, //获取手机型号 getPhoneBrand: function () { return JyObj.IosCall("getPhoneBrand") }, //获取定位 getLocation: function () { return JyObj.IosCall("getLocation") }, //切换菜单 chooseTab: function (indexTab) { JyObjMessage["indexTab"] = indexTab; window.webkit.messageHandlers.chooseTab.postMessage(JyObjMessage); JyObj.clearMessage(); }, //打开照相机 skipCamera: function () { window.webkit.messageHandlers.skipCamera.postMessage(JyObjMessage); JyObj.clearMessage(); }, //打开相册 skipAlbum: function () { window.webkit.messageHandlers.skipAlbum.postMessage(JyObjMessage); JyObj.clearMessage(); }, //点击返回调用 judgeIsHidden: function (referer) { JyObjMessage["referer"] = referer; window.webkit.messageHandlers.judgeIsHidden.postMessage(JyObjMessage); JyObj.clearMessage(); }, //返回值 处理 IosCall: function (functionName, args) { if (args != "" && args != undefined) { JyObj.clearMessage(); } var payload = { "jsName": functionName, "arguments": args }; var res = prompt(JSON.stringify(payload)); if (res != "") { var resObj = JSON.parse(res) var type = resObj.type switch (type) { case "int": return parseInt(resObj.value) case "string": return resObj.value case "bool": if (resObj.value == "true") { return true } return false default: return "" } } return "" } } } } vTools.$env = { inWeiXin: vTools.isWeiXinBrower(), platform: vTools.isWeiXinBrower() ? 'wx' : 'app', operateSystem: vTools.androidOrIOS() } // iosApp全局注册内置方法 if (!vTools.$env.inWeiXin && vTools.$env.operateSystem === 'ios') { vTools.iosAppFns() } /* * 时间格式化函数(将时间格式化为,2019年08月12日,2019-08-12,2019/08/12的形式) * * * pattern参数(想要什么格式的数据就传入什么格式的数据) * · 'yyyy-MM-dd' ---> 输出如2019-09-20 * · 'yyyy-MM-dd hh:mm' ---> 输出如2019-09-20 08:20 * · 'yyyy-MM-dd hh:mm:ss' ---> 输出如2019-09-20 08:20:23 * · 'yyyy/MM/dd' ---> 输出如2019/09/20 * · 'yyyy年MM月dd日' ---> 输出如2019年09月20日 * · 'yyyy年MM月dd日 hh时mm分' ---> 输出如2019年09月20日 08时20分 * · 'yyyy年MM月dd日 hh时mm分ss秒' ---> 输出如2019年09月20日 08时20分23秒 * · 'yyyy年MM月dd日 hh时mm分ss秒 EE' ---> 输出如2019年09月20日 08时20分23秒 周二 * · 'yyyy年MM月dd日 hh时mm分ss秒 EEE' ---> 输出如2019年09月20日 08时20分23秒 星期二 * * 参考: https://www.cnblogs.com/mr-wuxiansheng/p/6296646.html */ Date.prototype.pattern = function (fmt) { var o = { 'y+': this.getFullYear(), 'M+': this.getMonth() + 1, //月份 'd+': this.getDate(), //日 'h+': this.getHours() % 12 == 0 ? 12 : this.getHours() % 12, //小时 'H+': this.getHours(), //小时 'm+': this.getMinutes(), //分 's+': this.getSeconds(), //秒 'q+': Math.floor((this.getMonth() + 3) / 3), //季度 'S': this.getMilliseconds(), //毫秒 'E+': this.getDay(), // 周 }; var week = { '0': '日', '1': '一', '2': '二', '3': '三', '4': '四', '5': '五', '6': '六' }; if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length)); } if (/(E+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? '星期' : '周') : '') + week[ this.getDay() + '']); } for (var k in o) { if (new RegExp('(' + k + ')').test(fmt)) { fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]) .length))); } } return fmt; }