var comm = { data: { baseUrl: '' }, /* ====================================================================================== */ addEvent: function (ele, ev, fn) { // 添加事件的函数 //针对IE浏览器 if (ele.attachEvent) { ele.attachEvent('on' + ev, fn) } //针对FF与chrome else { ele.addEventListener(ev, fn, false) } }, ajax: function (options) { // 封装ajax var _this = this; //异步请求对象的完成状态 this.done = 0; this.format = function () { var now = new String(new Date().getTime()); return now.substr(0, now.length - 3); } //格式化参数 this.formatParams = function (data) { //获取地址参数 var arr = []; for (var name in data) { arr.push(encodeURIComponent(name) + "=" + encodeURIComponent(data[name])); } arr.push("t=" + _this.format());//按分钟刷一次 return arr.join("&"); } //传入设置 options = options || {}; //请求方式 options.type = (options.type || "GET").toUpperCase(); options.dataType = options.dataType || "json"; options.async = options.async || true; options.contentType = options.contentType || 'application/x-www-form-urlencoded'; var params = _this.formatParams(options.data); if (options.contentType == "application/json;charset=utf-8") { params = JSON.stringify(options.data) } //创建异步请求对象 - 第一步 var xhr; //w3c标准 if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } //兼容IE6及以下 else if (window.ActiveObject) { xhr = new ActiveXObject('Microsoft.XMLHTTP'); } //连接 和 发送 - 第二步 //判断是那种类型的请求 //若是get请求 if (options.type == "GET") { //参数拼接 if (options.url.indexOf("?") == -1) sp = "?"; else sp = "&"; //发送请求 xhr.open("GET", options.url + sp + params, options.async); xhr.send(null); } //若是post请求 else if (options.type == "POST") { //发送请求 xhr.open("POST", options.url, options.async); //设置表单提交时的内容类型 xhr.setRequestHeader("Content-Type", options.contentType); //参数配置 xhr.send(params); } //接收 - 第三步 xhr.onreadystatechange = function () { if (xhr.readyState == 4) { //状态码 var status = xhr.status; //状态码表示成功时,执行成功回调函数 if (status >= 200 && status < 300 || status == 304) { //返回数据的格式 //json字符串 if (options.dataType == "json") { try { options.success && options.success(eval("(" + xhr.responseText + ")")); } catch (err) { options.success && options.success(JSON.parse(xhr.responseText), xhr.responseXML); } } //普通字符串 else { options.success && options.success(xhr.responseText, xhr.responseXML); } // 改变状态为完成 _this.done = 1; } //如果状态码表示失败时调用错误处理回调函数 else { options.error && options.error(status); // 改变状态为完成 _this.done = 1; } } } }, /* ====================================================================================== */ hasClass: function (ele, cls) { // 判断一个类是否存在 return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')) }, addClass: function (ele, cls) { // 增加一个类 if (!this.hasClass(ele, cls)) ele.className = ele.className.replace(/(\s*$)/g, "") + " " + cls }, removeClass: function (ele, cls) { // 删除一个类 if (this.hasClass(ele, cls)) { var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)'); ele.className = ele.className.replace(reg, ' ') } }, getStyle: function (ele, attr) { // 获取某个元素的样式 var res = ''; if (window.getComputedStyle) { res = getComputedStyle(ele)[attr]; } else if (ele.currentStyle) { res = ele.currentStyle[attr]; } else { res = ele.style[attr]; } // 这里返回的样式做了调整,返回必须为字符串,有盒子的样式获取像margin-left会返回纯数字(不含单位px),这样不好处理,统一变成字符串后再对返回结果用正则匹配 return res + ''; }, /* ====================================================================================== */ show: function (ele) { // 让一个元素隐藏(display) ele.style.display = 'block' }, hide: function (ele) { // 让一个元素显示(display) ele.style.display = 'none' }, isShow: function (ele) { // 判断某个元素的是否显示(display,浅) var getVisibility = ele.style.display; return getVisibility !== "none"; }, isShowDeel: function (ele) { // 判断某个元素是否显示(display,深) temp = ele var getVisibility = this.getStyle(temp, 'display'); if (getVisibility == 'none') { return false; } else if (temp.tagName == 'BODY') { return true; } else { return this.isShowDeel(temp.parentNode); } }, visible: function (ele) { // 让一个元素隐藏(visible) ele.style.visibility = 'visible' }, hidden: function (ele) { // 让一个元素显示(visible) ele.style.visibility = 'hidden' }, /* ====================================================================================== */ addElement: function (ele, tag, cls, data, inner, fn) { // 为一个元素创建一个子元素 // 1、创建新元素 var newEle = document.createElement(tag) // 2、设置各种属性(图片地址,自定义属性等) newEle.setAttribute('class', cls); for (var item in data) { newEle.setAttribute(item, data[item]); } // 3、设置内容(innerhtml) newEle.innerHTML = inner ? inner : '' // 4、设置回调函数 fn && fn(newEle) // 5、将新元素加入到父元素中 ele.appendChild(newEle) }, /* ====================================================================================== */ setCookie: function (name, value, t) { // 设置cookie var hour = t ? t : 8; var exp = new Date(); exp.setTime(exp.getTime() + hour * 60 * 60 * 1000); document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString() + ";path=/"; }, getCookie: function (name) { // 获取cookie 存在返回值,不存在返回null var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)"); if (arr = document.cookie.match(reg)) { if (arr[2] != "undefined") return unescape(arr[2]); else return undefined; } else { return null; } }, getStack: function (stackName) { //获取历史栈 var _this = this; var stack; if (_this.getQueryString('stack')) { stack = JSON.parse(_this.getQueryString('stack')); } else if ( _this.getCookie(stackName) && JSON.parse(_this.getCookie(stackName)) ) { stack = JSON.parse(_this.getCookie(stackName)) } // 如果cookie上没有,就把上一页路径做为返回路径 else { stack = []; } return stack; }, pushStack: function (stackName, url) { // 添加历史栈 var _this = this; var stack; stack = _this.getStack(stackName); stack.push(url); _this.setCookie('stackName', JSON.stringify(stack)); _this.setCookie(stackName, JSON.stringify(stack)); }, popStack: function (stackName) { // 删除历史栈 var _this = this; var stack; var delTop; stack = _this.getStack(stackName); delTop = stack.pop(); _this.setCookie(stackName, JSON.stringify(stack)); return delTop; }, /* ====================================================================================== */ getQueryString: function (name) { // 获取url的某个参数 var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); var r = window.location.search.substr(1).match(reg); if (r != null && unescape(r[2]) != "undefined" && unescape(r[2]) != "null") return unescape(r[2]); return ''; }, urlParam: function (obj) { // 将对象转换为url参数字符串 var _this = this; var arr = []; for (var name in obj) { arr.push(encodeURIComponent(name) + "=" + encodeURIComponent(obj[name])); } return arr.join("&"); }, getRandom: function (min, max) { // 获取随机数 return Math.floor(Math.random() * (max - min)) + min; }, arrRandom: function (arr) { // 使数组随机排序,返回一个新数组 // var newArr = [] // var oldArrLength = arr.length // for(var i = 0; i < oldArrLength; i++) { // newArr.push(arr.splice(getRandom(0,arr.length),1)[0]) // } // return newArr arr.sort(function () { return 0.5 - Math.random() }) }, /* ====================================================================================== */ isPoneAvailable: function (pone) { // 判断是否为有效手机号 var myreg = /^[1][3,4,5,7,8][0-9]{9}$/; if (!myreg.test(pone)) { return false; } else { return true; } }, timestamp: function (time) { // 转换时间格式 var sec = Math.floor(time % 60) var min = Math.floor(time / 60 % 60) var hour = Math.floor(time / 60 / 60) sec = sec < 10 ? '0' + sec : sec min = min < 10 ? '0' + min : min hour = hour < 10 ? '0' + hour : hour var timeStr = hour + ':' + min + ':' + sec; return timeStr }, /* ====================================================================================== */ Debuglog: function (text) { // 弹窗,用于测试 if (typeof printWind == "undefined") { window.printWind = document.createElement("div"); window.inner = document.createElement("div"); inner.style.width = "600px"; inner.style.position = "absolute"; inner.style.right = "0px"; printWind.appendChild(inner); printWind.style.position = "fixed"; printWind.style.right = "0"; printWind.style.top = "0"; printWind.style.background = "rgba(0,0,0,0.6)"; printWind.style.zIndex = "99999"; printWind.style.padding = "20px"; printWind.style.fontSize = "20px"; printWind.style.width = "600px"; printWind.style.height = "600px"; printWind.style.color = "#0aff08"; document.body.appendChild(printWind); } var para = document.createElement("p"); //创建新的

元素 para.innerHTML = text; para.setAttribute("class", "newLine"); para.style.padding = "5px"; inner.appendChild(para); var a = inner.clientHeight - 600; inner.style.top = -a + "px"; }, STBUtil: { /** * 通过键值获取机顶盒对应信息 * @param name [参数名] ex:UserToken--用户token,EPGDomain--EPG域名,areaid--地区编码,templateName--当前用户模板 * @return [] */ getSTBKey: function (name) { var value = ''; if (typeof (Authentication) === "object") { if (Authentication.CTCGetConfig) { value = Authentication.CTCGetConfig(name); } else if (Authentication.CUGetConfig) { value = Authentication.CUGetConfig(name); } } return value; }, /** * 通过键值设置机顶盒对应信息 * @param name [参数名] * @param value [参数值] */ setSTBKey: function (name, value) { if (typeof (Authentication) === "object") { Authentication.CTCSetConfig(name, value); } }, /** * 获取机顶盒 用户账号/业务账号 * @return {string} */ getSTBUserId: function () { var userId = ''; try{ if (typeof (Authentication) == 'object') { // 此方法经测试目前可以获取到华为,中兴,创维三款机顶盒型号 userId = Authentication.CTCGetConfig('UserID'); if (!userId){ userId = Authentication.CUGetConfig("UserID"); } //烽火的机顶盒 if(!userId){ userId =Authentication.CTCGetConfig("device.userid"); } //中兴老的盒子获取机顶盒型号的方法 if(!userId && typeof(ztebw) == 'object' ){ stbModel = ztebw.ioctlRead("infoZTEHWType"); if(!stbModel) { stbModel = ztebw.ioctlRead("infoHWProduct"); } } } else{ console.log("不支持Authentication!"); } } catch(e){ userId = ''; } return userId; }, /** * 获取机顶盒 设备ID * @return {string} */ getSTBId: function () { var stbId = ""; if (typeof (Authentication) == "object") { stbId = Authentication.CTCGetConfig("STBID"); if (!stbId) { stbId = Authentication.CUGetConfig("STBID"); } if (!stbId) { stbId = Authentication.CTCGetConfig("device.stbid"); // 烽火的机顶盒 } } // 广西广电获取stbId if (!stbId && typeof (guangxi) === "object") { stbId = guangxi.getStbNum(); } return stbId; }, /** * 获取机顶盒型号 * @return {string} */ getSTBModel: function () { var stbModel = ''; try{ //此方法经测试目前可以获取到华为,中兴,创维三款机顶盒型号 stbModel = Authentication.CTCGetConfig('STBType'); if (!stbModel){ stbModel = Authentication.CUGetConfig("STBType"); } //烽火的机顶盒 if(!stbModel){ stbModel = Authentication.CTCGetConfig("device.stbmodel"); } //中兴老的盒子获取机顶盒型号的方法 if(!stbModel && typeof(ztebw) == 'object' ){ stbModel = ztebw.ioctlRead("infoZTEHWType"); if(!stbModel){ stbModel = ztebw.ioctlRead("infoHWProduct"); } } } catch(e){ console.log("不支持获取机顶盒型号!"); } return stbModel; }, /** * 获取机顶盒mac地址 * @return {string} */ getSTBMac: function () { if (window.isWinOS) { //Windows操作系统 return "00-00-00-00-00-00"; } var mac = ""; if (typeof (Authentication) == "object") { try { mac = Authentication.CUGetConfig("mac"); if (!mac && typeof (ztebw) == "object") { var stbId = ztebw.ioctlRead("infoHWSN"); mac = stbId.substring(stbId.length - 12); } if (!mac) { mac = Authentication.CTCGetLocalMAC(); } } catch (e) { } } // 广西广电获取mac if (!mac && typeof iPanel === "object") { mac = iPanel.getGlobalVar("MAC_ETH0"); } // 长虹机顶盒获取mac(四川广电) if (!mac && typeof (Ethernet) === "object") { mac = Ethernet.MACAddress; } if (mac) { while (mac.indexOf(":") !== -1) { mac = mac.replace(":", ""); } } else { mac = "00-00-00-00-00-00"; } return mac; }, /** * 获取 EPG大厅地址 * @return {string} */ getEPGDomain: function () { var epgDomain = ""; if (typeof (Authentication) == "object") { epgDomain = Authentication.CTCGetConfig("EPGDomain"); if (!epgDomain) { epgDomain = Authentication.CUGetConfig("EPGDomain"); } if (typeof epgDomain === "undefined" || epgDomain == null) { epgDomain = ""; } } return epgDomain; }, /** * 获取 UserToken * @return {string} */ getUserToken: function () { var userToken = ""; if (typeof (Authentication) == "object") { userToken = Authentication.CTCGetConfig("UserToken"); if (!userToken) { userToken = Authentication.CUGetConfig("UserToken"); } if (!userToken) { userToken = Authentication.CTCGetConfig("device.usertoken"); } } return userToken; }, } }; // promise插件 (function (window) { // 参考Joe-Xie:https://www.cnblogs.com/XieJunBao/p/9156134.html // 原生封装promise为了应对低版本浏览器不兼容问题 // 异步串行思路:promise执行then是注册回调函数,then有多个就可以注册多个回调函数,但是若多个回调都是异步执行的,那我们要等上一个异步结束后才执行下一个异步,这是时候就需要上一个异步操作完成后,把这个完成状态告诉下一个回调,这样才可以异步串行。为了解决这个问题我们把异步完成状态托管给promise去管理 // 流程:第一步注册:链式调用then函数,每执行一个then函数,返回一个桥梁promise(then函数中的成功回调和失败回调是写入这个promise的回调列表中的,注意成功回调的功能除了执行本身函数外还要更新下一个promise的状态) // 第二步执行:第一个promise的异步执行完,开始执行第一个promise的回调函数(回调函数又分两步走:第一步:resolvePromise解析回调返回值(如果是promise则说明是异步,就需要继续解析直到不是promise而是一个具体的值),第二步:当回调返回的值是一个具体值而不是promise时,调用第二个proomise的reslove方法将第二个proomise的状态更新为fulfilled,并将第一个promise的回调的值传入p2的回调函数中去执行) function MyPromise(fn) { var self = this; // 成功回调传的参数 self.value = null; // 失败回调传的参数 self.error = null; // 当前promise对象的状态 self.status = "pending"; // 存储成功回调列表 self.onFulfilledCallbacks = []; // 存储失败回调列表 self.onRejectedCallbacks = []; // 状态改变并执行回调 // 成功 function resolve(value) { // 判断传入参数是否由MyPromise构造的对象,若是,注册该函数 if (value instanceof MyPromise) { return value.then(resolve, reject); } // 判断 if (self.status === "pending") { setTimeout(function () { self.status = "fulfilled"; self.value = value; // 执行成功回调 // self.onFulfilledCallbacks.forEach(function(callback){callback(self.value)}); // 向下兼容forEach for (var i = 0; i < self.onFulfilledCallbacks.length; i++) { self.onFulfilledCallbacks[i](self.value); } }, 0) } } // 失败 function reject(error) { if (self.status === "pending") { setTimeout(function () { self.status = "rejected"; self.error = error; // self.onRejectedCallbacks.forEach(function(callback){callback(self.error)}); for (var i = 0; i < self.onRejectedCallbacks.length; i++) { self.onRejectedCallbacks[i](self.error); } }, 0) } } try { fn(resolve, reject); } catch (e) { reject(e); } } // 解析放回值 // 用来解析回调函数的返回值x,x可能是普通值也可能是个promise对象 // 因为回调函数既可能会返回一个异步的promise也可能会返回一个同步结果,所以我们把直接把回调函数的结果托管给bridgePromise,使用resolvePromise方法来解析回调函数的结果,如果回调函数返回一个promise并且状态还是pending,就在这个promise的then方法中继续解析这个promise reslove传过来的值,如果值还是pending状态的promise就继续解析,直到不是一个异步promise,而是一个正常值就使用bridgePromise的reslove方法将bridgePromise的状态改为fulfilled,并调用onFulfilledCallbacks回调数组中的方法,将该值传入,到此异步操作就衔接上了。 function resolvePromise(bridgepromise, x, resolve, reject) { // bridgepromise是桥梁promise,x是桥梁promise中注册的成功回调的返回值,resolve和reject是桥梁promise的状态改变函数 // 2.3.1规范,避免循环引用 // 如果成功回调的值又是桥梁promise就返回循环传参的错误(死循环) if (bridgepromise === x) { return reject(new TypeError('Circular reference')); } var called = false; // // 如果x是一个promise,则通过递归 // if (x instanceof MyPromise) { // //如果这个promise是pending状态,就在它的then方法里继续执行resolvePromise解析它的结果,直到返回值不是一个pending状态的promise为止(这里使用了递归的方法) // if (x.status === "pending") { // x.then( // function(y){ // resolvePromise(bridgepromise, y, resolve, reject); // }, // function(error){ // reject(error); // } // ); // } // else { // x.then(resolve, reject); // } // } // else // // 如果x是一个promise,则继续解析它的状态 if (x != null && ((typeof x === 'object') || (typeof x === 'function'))) { try { var then = x.then; if (typeof then === 'function') { // then方法的指向传入的桥梁promise,也就是说该桥梁promise调用了then方法并传入了成功回调和失败回调 then.call( x, // 传入then的成功回调 function (y) { if (called) return; called = true; // 这里重新解析当前的桥梁promise,至于成功回调的返回值传空(这里目的是通过递归持续判断当前桥梁promise的状态) resolvePromise(bridgepromise, y, resolve, reject); }, //传入then的失败回调 function (error) { if (called) return; called = true; reject(error); } ) } // 如果then不是一个函数,则以x为值改变promise状态并延长成功回调列表 else { resolve(x); } } // 如果在取x.then值时抛出了异常,则以这个异常做为原因将promise拒绝。 catch (e) { if (called) return; called = true; reject(e); } } // 如过x不是一个promise,则改变bridgePromise的状态改为fulfilled,并调用onFulfilledCallbacks回调数组中的方法,将该值传入 else { resolve(x); } } // 注册回调函数 MyPromise.prototype.then = function (onFulfilled, onRejected) { var self = this; // 搭建桥梁promise(即调用为then方法后重新返回一个新的promise对象) var bridgePromise; // 防止使用者不传成功或失败回调函数,所以成功失败回调都给了默认回调函数 onFulfilled = typeof onFulfilled === "function" ? onFulfilled : function (value) { return value }; onRejected = typeof onRejected === "function" ? onRejected : function (error) { throw error }; // 如果当前的promise对象是完成状态 // 返回一个新的桥梁promise if (self.status === "fulfilled") { return bridgePromise = new MyPromise(function (resolve, reject) { setTimeout(function () { try { // 获取成功回调函数的返回值 var x = onFulfilled(self.value); // 解析桥梁promise函数 resolvePromise(bridgePromise, x, resolve, reject); } catch (e) { reject(e); } }, 0); }) } // 如果当前的promise对象是拒绝状态 if (self.status === "rejected") { return bridgePromise = new MyPromise(function (resolve, reject) { setTimeout(function () { try { var x = onRejected(self.error); resolvePromise(bridgePromise, x, resolve, reject); } catch (e) { reject(e); } }, 0); }); } // 如果当前的promise对象是听候状态,则在当前promise对象的成功回调列表和失败回调列表中注入 if (self.status === "pending") { return bridgePromise = new MyPromise(function (resolve, reject) { // 注意回调列表是把整个回调函数和回调解析函数一起注入的!!!!!,所以在执行回调时除运行回调函数还要,解析桥梁promise的状态(有可能桥梁promise中也有promise),解析中改变当前promise的状态,若当前promise的状态为完成状态才继续执行下一个注册好的回调 self.onFulfilledCallbacks.push(function (value) { try { var x = onFulfilled(value); resolvePromise(bridgePromise, x, resolve, reject); } catch (e) { reject(e); } }); self.onRejectedCallbacks.push(function (error) { try { var x = onRejected(error); resolvePromise(bridgePromise, x, resolve, reject); } catch (e) { reject(e); } }); }); } } MyPromise.prototype.MyCatch = function (onRejected) { return this.then(null, onRejected); } MyPromise.all = function (promises) { return new MyPromise(function (resolve, reject) { var result = []; var count = 0; for (var i = 0; i < promises.length; i++) { // (function(i){ // return promises[i].then(function(data) { // result[i] = data; // if (++count == promises.length) { // resolve(result); // } // }, function(error) { // reject(error); // }); // })(i) function closeTemp(i) { return promises[i].then(function (data) { result[i] = data; if (++count == promises.length) { resolve(result); } }, function (error) { reject(error); }); } closeTemp(i) } }); } MyPromise.race = function (promises) { return new MyPromise(function (resolve, reject) { for (var i = 0; i < promises.length; i++) { promises[i].then(function (data) { resolve(data); }, function (error) { reject(error); }); } }); } MyPromise.resolve = function (value) { return new MyPromise(function (resolve) { resolve(value); }); } MyPromise.reject = function (error) { return new MyPromise(function (resolve, reject) { reject(error); }); } MyPromise.promisify = function (fn) { return function () { var args = Array.from(arguments); return new MyPromise(function (resolve, reject) { fn.apply(null, args.concat(function (err) { err ? reject(err) : resolve(arguments[1]) })); }) } } window.MyPromise = MyPromise; })(window);