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) { // 让一个元素隐藏(visibility) ele.style.visibility = 'visible' }, hidden: function (ele) { // 让一个元素显示(visibility) ele.style.visibility = 'hidden' }, visibleClass: function (cls) { // 让一个类的元素隐藏(visibility) var arr = document.getElementsByClassName(cls) for (var i = 0; i < arr.length; i++) { arr[i].style.visibility = 'visible' } }, hiddenClass: function (cls) { // 让一个类的元素显示(visibility) var arr = document.getElementsByClassName(cls) for (var i = 0; i < arr.length; i++) { arr[i].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) }, // 帧动画(定时器容器(存在一个对象内的一个属性),图片群所在的元素,执行速度(单位:毫秒),是否只执行一次,执行完毕的回调函数) zhenAnimation: function (interval, ele, speed, once, fn) { var cont = document.getElementsByClassName('container')[0] // 清除定时器 clearInterval(cont[interval]) // 获取图片群并全部隐藏 var imgs = ele.getElementsByTagName('img') for (var i = 0; i < imgs.length; i++) { imgs[i].style.visibility = 'hidden' } // 单独显示第一张图 var i = 0 imgs[i].style.visibility = 'visible' // 设置定时器 cont[interval] = setInterval(function() { // 判断是否只执行一次 if (i == imgs.length-1 && once) { // 每轮执行完成的回调函数 clearInterval(cont[interval]) fn&&fn() return } // 前一张图隐藏、后一张图显现、可循环执行 imgs[i++].style.visibility = 'hidden' if (i == imgs.length) {i=0; fn&&fn()} imgs[i].style.visibility = 'visible' }, speed) }, // 帧动画加强版,ele格式:
元素 para.innerHTML = text; para.setAttribute("class", "newLine"); para.style.padding = "5px"; inner.appendChild(para); var a = inner.clientHeight - 600; inner.style.top = -a + "px"; }, tips: function (text, time) { time = time ? time : 1500; var para = document.createElement("div"); //创建新的
元素 para.innerHTML = text; para.style.zIndex = 10000; para.style.borderRadius = '9px' para.style.backgroundColor = '#287AFF' para.style.textAlign = 'center' para.style.color = '#FFF' para.style.position = 'absolute' para.style.fontSize = '20px' para.style.left = '450px' para.style.top = '250px' para.style.padding = '7px 27px' para.style.width = '380px' para.style.wordBreak = 'break-all' para.style.display = 'block' document.body.appendChild(para); setTimeout(function () { document.body.removeChild(para); }, time); }, /* ====================================================================================== */ 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);