///////////// //headerfix.js ///////////// (window.constructQZFL = function(){ //})(); ///////////// //qzfl.js ///////////// /** * @fileOverview QZFL 主框架逻辑,
Qzone Front-end Library: Liberation
QZFL 是由空间平台开发组,开发的一套js框架库。
QZFL 最后的 L 有两个意思,其中一个意思是 Library 功能库,说明这是一个前台的框架库;
同时 L 也是 Liberation 解放的意思,这是希望通过 QZFL 能把大家在JS开发工作中解放出来。 QZFL各种合并版本都必须包含本源文件 * @version 2.0.9.6 ($Rev: 1921 $) * @author QzoneWebGroup - ($LastChangedBy: ryanzhao $) - ($Date: 2011-01-11 18:46:01 +0800 (周二, 11 一月 2011) $) */ /** * QZFL名字空间 * @namespace QZFL名字空间 * @name QZFL */ window.QZFL = window.QZONE = window.QZFL || window.QZONE || {}; /** * 版本号说明字 * @type string */ QZFL.version = "2.1.60"; /** * 版本号数字 * @public * @type number */ QZFL._qzfl = 2.151; /** * 定义一个通用空函数 * @returns {undefined} */ QZFL.emptyFn = function() {}; /** * 定义一个通用透传函数 * @param {number|string|object|function|undefined} [v = undefined] * @returns {number|string|object|function|undefined} 就是传入的v直接透传出来 */ QZFL.returnFn = function(v) { return v; }; /** * 浏览器判断引擎,给程序提供浏览器判断的接口 * @namespace 浏览器判断引擎 * @name userAgent * @memberOf QZFL */ (function(){ var ua = QZFL.userAgent = {} , agent = navigator.userAgent , nv = navigator.appVersion , r , m , optmz; /** * 调整浏览器的默认行为,使之优化 * @deprecated 已经不建议显式调用了,由QZFL初始化时调用 * @function * @static * @name adjustBehaviors * @memberOf QZFL.userAgent */ ua.adjustBehaviors = QZFL.emptyFn; if (window.ActiveXObject || window.msIsStaticHTML) {//ie (document.querySelectorAll) or IE11 /** * IE版本号,如果不是IE,此值为 NaN * @field * @type number * @static * @name ie * @memberOf QZFL.userAgent */ ua.ie = 6; (window.XMLHttpRequest || (agent.indexOf('MSIE 7.0') > -1)) && (ua.ie = 7); (window.XDomainRequest || (agent.indexOf('Trident/4.0') > -1)) && (ua.ie = 8); (agent.indexOf('Trident/5.0') > -1) && (ua.ie = 9); (agent.indexOf('Trident/6.0') > -1) && (ua.ie = 10); (agent.indexOf('Trident/7.0') > -1) && (ua.ie = 11); /** * 当前的IE浏览器是否为beta版本 * @field * @type boolean * @static * @name isBeta * @memberOf QZFL.userAgent */ ua.isBeta = navigator.appMinorVersion && navigator.appMinorVersion.toLowerCase().indexOf('beta') > -1; //一些浏览器行为矫正 if (ua.ie < 7) {//IE6 背景图强制cache try { document.execCommand('BackgroundImageCache', false, true); } catch (ign) {} } //创建一个document引用 QZFL._doc = document; //扩展IE下两个setTime的传参能力 optmz = function(st){ return function(fns, tm){ var aargs; if(typeof fns == 'string'){ return st(fns, tm); }else{ aargs = Array.prototype.slice.call(arguments, 2); return st(function(){ fns.apply(null, aargs); }, tm); } }; }; window.setTimeout = QZFL._setTimeout = optmz(window.setTimeout); window.setInterval = QZFL._setInterval = optmz(window.setInterval); } else if (document.getBoxObjectFor || typeof(window.mozInnerScreenX) != 'undefined') { r = /(?:Firefox|GranParadiso|Iceweasel|Minefield).(\d+\.\d+)/i; /** * FireFox浏览器版本号,非FireFox则为 NaN * @field * @type number * @static * @name firefox * @memberOf QZFL.userAgent */ ua.firefox = parseFloat((r.exec(agent) || r.exec('Firefox/3.3'))[1], 10); } else if (!navigator.taintEnabled) {//webkit m = /AppleWebKit.(\d+\.\d+)/i.exec(agent); /** * Webkit内核版本号,非Webkit则为 NaN * @field * @type number * @static * @name webkit * @memberOf QZFL.userAgent */ ua.webkit = m ? parseFloat(m[1], 10) : (document.evaluate ? (document.querySelector ? 525 : 420) : 419); if ((m = /Chrome.(\d+\.\d+)/i.exec(agent)) || window.chrome) { /** * Chrome浏览器版本号,非Chrome浏览器则为 NaN * @field * @type number * @static * @name chrome * @memberOf QZFL.userAgent */ ua.chrome = m ? parseFloat(m[1], 10) : '2.0'; } else if ((m = /Version.(\d+\.\d+)/i.exec(agent)) || window.safariHandler) { /** * Safari浏览器版本号,非Safari浏览器则为 NaN * @field * @type number * @static * @name safari * @memberOf QZFL.userAgent */ ua.safari = m ? parseFloat(m[1], 10) : '3.3'; } /** * 当前页面是否为air client * @field * @type boolean * @static * @name air * @memberOf QZFL.userAgent */ ua.air = agent.indexOf('AdobeAIR') > -1 ? 1 : 0; /** * 是否为iPod客户端页面 * @field * @type boolean * @static * @name isiPod * @memberOf QZFL.userAgent */ ua.isiPod = agent.indexOf('iPod') > -1; /** * 是否为iPad客户端页面 * @field * @type boolean * @static * @name isiPad * @memberOf QZFL.userAgent */ ua.isiPad = agent.indexOf('iPad') > -1; /** * 是否为iPhone客户端页面 * @field * @type boolean * @static * @name isiPhone * @memberOf QZFL.userAgent */ ua.isiPhone = agent.indexOf('iPhone') > -1; } else if (window.opera) {//opera /** * Opera浏览器版本号,非Opera则为 NaN * @field * @type number * @static * @name opera * @memberOf QZFL.userAgent */ ua.opera = parseFloat(window.opera.version(), 10); } else {//默认IE6吧 ua.ie = 6; } /** * 是否为MacOS * @field * @type boolean * @static * @name macs * @memberOf QZFL.userAgent */ if (!(ua.macs = agent.indexOf('Mac OS X') > -1)) { /** * Windows操作系统版本号,不是的话为NaN * @field * @type number * @static * @name windows * @memberOf QZFL.userAgent */ ua.windows = ((m = /Windows.+?(\d+\.\d+)/i.exec(agent)), m && parseFloat(m[1], 10)); /** * 是否Linux操作系统,不是的话为false * @field * @type boolean * @static * @name linux * @memberOf QZFL.userAgent */ ua.linux = agent.indexOf('Linux') > -1; /** * 是否Android操作系统,不是的话为false * @field * @type boolean * @static * @name android * @memberOf QZFL.userAgent */ ua.android = agent.indexOf('Android') > -1; } /** * 是否iOS操作系统,不是的话为false * @field * @type boolean * @static * @name iOS * @memberOf QZFL.userAgent */ ua.iOS = agent.indexOf('iPhone OS') > -1; !ua.iOS && (m = /OS (\d+(?:_\d+)*) like Mac OS X/i.exec(agent), ua.iOS = m && m[1] ? true : false); })(); /** * QZFL对Javascript Object的接口封装,提供一些原生能力 * @namespace 对象基础处理 */ QZFL.object = { /** * 把命名空间的方法映射到全局 * @param {object} object 对象 * @param {object} [scope=window] 目标空间 * @deprecated 不推荐常使用,避免变量名冲突 * @example * QZFL.object.map(QZFL.lang) */ map : function(object, scope) { return QZFL.object.extend(scope || window, object); }, /** * 命名空间功能扩展 * @param {object} namespace 需要被扩展的命名空间 * @param {object} extendModule 需要扩展的功能包 * @returns {object} 返回被扩展的命名空间,即扩展后的namespace * @example * QZFL.object.extend(QZFL.dialog, { fn1: function(){} } ); */ extend : function() { var args = arguments, len = arguments.length, deep = false, i = 1, target = args[0], opts, src, clone, copy; if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; i = 2; } if ( typeof target !== "object" && typeof target !== "function" ) { target = {}; } if ( len === i ) { target = QZFL; --i; } for ( ; i < len; i++ ) { if ( (opts = arguments[ i ]) != null ) { for (var name in opts ) { src = target[ name ]; copy = opts[ name ]; if ( target === copy ) { continue; } if ( deep && copy && typeof copy === "object" && !copy.nodeType ) { if ( src ) { clone = src; } else if ( QZFL.lang.isArray(copy) ) { clone = []; } else if ( QZFL.object.getType(copy) === 'object' ) { clone = {}; } else { clone = copy; } target[ name ] = QZFL.object.extend( deep, clone, copy ); } else if ( copy !== undefined ) { target[ name ] = copy; } } } } return target; }, /** * 对对象成员批量执行一个操作 * * @param {object} obj 被操作对象对象 * @param {function} callback 所执行的操作 * @returns {object} 传入的obj对象 * @example * QZFL.object.each([1,2,3], function(){ alert(this) } ); */ each : function(obj, callback) { var value, i = 0, length = obj.length, isObj = (length === undefined) || (typeof(obj)=="function"); if (isObj) { for (var name in obj) { if (callback.call(obj[name], obj[name], name, obj) === false) { break; } } } else { for (value = obj[0]; i < length && false !== callback.call(value, value, i, obj); value = obj[++i]) { } } return obj; }, /** * 获取对象类型 * * @param {object} obj 任意一个数据 * @return {string} 返回对象类型字符串 * @example * QZFL.object.getType([1,2,3]); */ getType : function(obj) { return obj === null ? 'null' : (obj === undefined ? 'undefined' : Object.prototype.toString.call(obj).slice(8, -1).toLowerCase()); }, /** * route用到的正则对象 * @field * @static * @private * @type RegExp * @default /([\d\w_]+)/g */ routeRE : /([\d\w_]+)/g, /** * 用对象路径取一个JSON对象中的子对象引用 * @static * @param {object} obj 源对象 * @param {string} path 对象获取路径 * @returns {object|string|number|function} * @example * QZFL.object.route( { "a" : { "b" : { "c" : "Hello World" } } }, "a.b.c" ); //返回值:"Hello World" */ route: function(obj, path){ obj = obj || {}; path = String(path); var r = QZFL.object.routeRE, m; r.lastIndex = 0; while ((m = r.exec(path)) !== null) { obj = obj[m[0]]; if (obj === undefined || obj === null) { break; } } return obj; }, /** * 将方法绑定在对象上,能够保护this指针不会“漂移” * @param {object} obj 母体对象 * @param {object} fn 目标方法 * @example var e = QZFL.event.bind(objA, funB); */ bind : function(obj, fn) { var slice = Array.prototype.slice, args = slice.call(arguments, 2); return function(){ obj = obj || this; fn = typeof fn == 'string' ? obj[fn] : fn; fn = typeof fn == 'function' ? fn : QZFL.emptyFn; return fn.apply(obj, args.concat(slice.call(arguments, 0))); }; }, /** * 把指定命名空间下的方法 以短名的方式 映射到另一个命名空间 * @param {object} src 源对象 * @param {object} tar 目标对象 * @param {function} [rule=function(name){ return '$' + name; }] 映射名字的处理器 * @returns {undefined} */ ease : function(src, tar, rule){ if (tar) { if (typeof(rule) != 'function') { rule = QZFL.object._eachFn; } QZFL.object.each(src, function(v, k){ if (typeof(v) == 'function') { tar[rule(k)] = v; } }); } }, /** * QZFL.object.ease 的命名映射默认方案 * @param {string} name 源名 * @returns {string} 转换后的名字 * @private */ _easeFn : function(name){ return '$' + name; } }; /** * QZFL对Javascript Object的接口封装,提供一些原生能力 Deprecated * @namespace 对象基础处理 * @deprecated 建议不要用这个了,用QZFL.object中的相关方法 * @see QZFL.object */ QZFL.namespace = QZFL.object; /** * QZFL 调试引擎接口,为调试提供接入的可能 * @namespace QZFL调试引擎接口 */ QZFL.runTime = { /** * 是否处于debug模式 * @field * @static * @type boolean * @default false */ isDebugMode : false, /** * 错误报告接口 * @function * @static * @type function * @default QZFL.emptyFn */ error : QZFL.emptyFn, /** * 警告信息报告接口 * @function * @static * @type function * @default QZFL.emptyFn */ warn : QZFL.emptyFn }; //--------------------------------------------- /** * qzfl 控制台,用于显示调试信息以及进行一些简单的脚本调试等操作 * @namespace QZFL控制台接口,用来显示程序输出的log信息。 */ QZFL.console = window.console || {};//function(expr){}; /** * 在console里显示信息 * @returns {undefined} */ QZFL.console.log = QZFL.console.log || function() {}; /** * 在console里显示信息 * @deprecated * @returns {undefined} */ QZFL.console.print = QZFL.console.log; //---------------------------------------------- /** * 各种功能各异的组件代码 * @namespace QZFL小组件包 * */ QZFL.widget = {}; //---------------------------------------------- //把QZFL.object下的方式直接映射到QZFL命名空间下 QZFL.object.map(QZFL.object, QZFL); ///////////// //qzone_config.js ///////////// /** * @author scorr */ (function(w){ QZFL.config = QZFL.config || {}; var preFix, cw = w; do{ try{ cw.siDomain && (QZFL.config.resourceDomain = cw.siDomain.replace("http://","").split("/")[0]); // siDomain 是Qzone业务逻辑的全局变量 cw.imgcacheDomain && (QZFL.config.domain = cw.imgcacheDomain.replace("http://","").split("/")[0]); // siDomain 是Qzone业务逻辑的全局变量 }catch(err){ //页面跨域就算了 break; } }while((cw !== cw.parent) && (cw = cw.parent)); QZFL.config.defaultMediaRate = 2; })(window); ///////////// //config.js ///////////// /** * @fileoverview QZFL全局配置文件 * @version $Rev: 1921 $ * @author QzoneWebGroup - ($LastChangedBy: ryanzhao $) - ($Date: 2011-01-11 18:46:01 +0800 (周二, 11 一月 2011) $) */ /** * QZFL配置,用来存储QZFL一些组件需要的参数 * @namespace QZFL配置 */ QZFL.config = QZFL.config || {}; /** * 调试等级 * @type number * @default 0 */ (typeof QZFL.config.debugLevel == 'undefined') && (QZFL.config.debugLevel = 0); /** * 默认与后台交互的编码 * * @type string * @default "GB2312" */ (typeof QZFL.config.defaultDataCharacterSet == 'undefined') && (QZFL.config.defaultDataCharacterSet = "GB2312"); /** * dataCenter中cookie存储的默认域名 * * @type string * @default "qzone.qq.com" */ (typeof QZFL.config.DCCookieDomain == 'undefined') && (QZFL.config.DCCookieDomain = "qzone.qq.com"); /** * 系统默认一级域名 * * @type string * @default "qq.com" */ (typeof QZFL.config.domainPrefix == 'undefined') && (QZFL.config.domainPrefix = "qq.com"); /** * 默认主域名 * */ (typeof QZFL.config.domain == 'undefined') && (QZFL.config.domain = "qzs.qq.com"); /** * 默认cookie free主域名 * */ (typeof QZFL.config.resourceDomain == 'undefined') && (QZFL.config.resourceDomain = "qzonestyle.gtimg.cn"); /** * XHR proxy的gbencoder dictionary路径(需要复写) * * @type string * @default "http://qzs.qq.com/qzone/v5/toolpages/" */ QZFL.config.gbEncoderPath = "http://" + QZFL.config.domain + "/qzone/v5/toolpages/"; /** * FormSender的helper page(需要复写) * * @type string * @default "http://qzs.qq.com/qzone/v5/toolpages/fp_gbk.html" */ QZFL.config.FSHelperPage = "http://" + QZFL.config.domain + "/qzone/v5/toolpages/fp_gbk.html"; /** * 默认flash ShareObject地址 * @type string * @default "http://qzs.qq.com/qzone/v5/toolpages/getset.swf" */ QZFL.config.defaultShareObject = "http://" + QZFL.config.resourceDomain + "/qzone/v5/toolpages/getset.swf"; /** * 默认静态页的server地址 * @type string * @default "http://qzs.qq.com/ac/qzone/qzfl/lc/" */ QZFL.config.staticServer = "http://" + QZFL.config.resourceDomain + "/ac/qzone/qzfl/lc/"; ///////////// //css.js ///////////// /** * @fileoverview QZFL样式处理,提供多浏览器兼容的样式表处理 * @version $Rev: 1921 $ * @author QzoneWebGroup ($LastChangedBy: ryanzhao $) - $Date: 2011-01-11 18:46:01 +0800 (周二, 11 一月 2011) $ */ /** * QZFL css 工具包,给浏览器提供基本的样式处理接口 * * @namespace QZFL css 工具包 */ QZFL.css = { /** * 用以匹配样式类名的正则池 * @private * @ignore * @type object */ classFileNameCache: {}, /** * 获取用以匹配样式类名的正则 * * @param {string} className 样式名称 * @returns {RegExp} 用以匹配的正则表达式规则 * @private * @deprecated 没啥大用 * getClassRegEx: function(className){ var o = QZFL.css.classNameCache; return o[className] || (o[className] = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)')); },*/ /** * 把16进制的颜色转换成10进制颜色的工具 * @param {string} color 十六进制颜色文本 * @returns {number[]} 返回数组形式的10进制颜色 * @example QZFL.css.convertHexColor("#ff00ff") //[255, 0, 255]; */ convertHexColor: function(color){ color = String(color || ''); color.charAt(0) == '#' && (color = color.substring(1)); color.length == 3 && (color = color.replace(/([0-9a-f])/ig, '$1$1')); return color.length == 6 ? [parseInt(color.substr(0, 2), 16), parseInt(color.substr(2, 2), 16), parseInt(color.substr(4, 2), 16)] : [0, 0, 0]; }, /** * 从RGB色彩模型到HSL色彩模型的转换算法 * @param {number} r 红色值,10进制整数,[0, 255] * @param {number} g 绿色值,10进制整数,[0, 255] * @param {number} b 蓝色值,10进制整数,[0, 255] * @return {object} result.h 是色相值 [0, 360) 度;result.s 是饱和度值[0, 1];result.l 是亮度值[0, 1] */ rgb2hsl: function(r, g, b){ var t , red = Math.max(r / 255, 0) , green = Math.max(g / 255, 0) , blue = Math.max(b / 255, 0) , max = Math.max(red, green, blue) , min = Math.min(red, green, blue) , result = { h : 0 , s : 0 , l : Math.max((max + min) / 2, 0) }; if(max != min){ if(max == red){ result.h = (t = 60 * ((green - blue) / (max - min))) < 0 ? (t + 360) : t; }else if(max == green){ result.h = (60 * ((blue - red) / (max - min)) + 120); }else if(max == blue){ result.h = (60 * ((red - green) / (max - min)) + 240); } if(result.l <= 0.5){ result.s = (max - min) / (2 * result.l); }else if(0.5 < result.l){ result.s = (max - min) / (2 - 2 * result.l); } result.h = Math.round(result.h); result.s = Math.round(result.s * 100) / 100; result.l = Math.round(result.l * 100) / 100; } return result; }, /** * 缓存当前页面的样式表对象引用的池 * * @private * @type object * @deprecated 不要再用了 * styleSheets: {},*/ /** * 通过id号获取样式表 * @param {string|number} id 样式表的编号 * @returns {object} 返回样式表对象,没有匹配则为null * @example QZFL.css.getStyleSheetById("div_id"); */ getStyleSheetById: function(id){ var s; return (s = QZFL.dom.get(id)) && s.sheet || (s = document.styleSheets) && s[id]; }, /** * 获取stylesheet的样式规则 * @param {string|number} id 样式表的编号 * @example QZFL.css.getRulesBySheet("css_id"); * @returns {object} 返回样式表规则集合对象,若未发生匹配则为空对象 */ getRulesBySheet: function(sheetId){ var ss = typeof(sheetId) == "object" ? sheetId : QZFL.css.getStyleSheetById(sheetId), rs = {}, head, base; if (ss && !(rs = ss.cssRules || ss.rules)) { if (head = document.getElementsByTagName('head')[0]) { if (base = head.getElementsByTagName('base')[0]) { QZFL.dom.removeElement(base); rs = ss.cssRules; head.appendChild(base); } } } return rs; }, /** * 根据选择器获得样式规则 * @param {string} sheetId id 样式表的编号 * @param {string} selector 选择器名称 * @returns {object} 返回匹配到的样式规则对象,未匹配则为null * @example QZFL.css.getRuleBySelector("css_id","#"); */ getRuleBySelector: function(sheetId, selector){ selector = (String(selector)).toLowerCase(); var _ss = QZFL.css.getStyleSheetById(sheetId), _rs = QZFL.css.getRulesBySheet(_ss); for (var i = 0, len = _rs.length; i < len; ++i) { if (selector == _rs[i].selectorText.toLowerCase()) { return _rs[i]; } } return null; }, /** * 插入外链样式表 * @param {string} url 外部css地址 * @param {string|object} [opts] 若类型为string则为link Element的ID,若为object则为可选参数包 * @param {string} [opts.linkID=undefined] link Element的ID * @param {string} [opts.doc=document] 被插入link节点的文档树根 * @param {string} [opts.media="screen"] 样式节点的media种类属性 * @returns {object} 返回样式表对象,插入失败返回的是link Element引用 * @example QZFL.css.insertCSSLink("/css/style.css", "myCSS1"); QZFL.css.insertCSSLink("/css/style.css", { linkID : "myCSS2", doc : frames["innerFrame"].document}); */ insertCSSLink: function(url, opts){ var sid , doc , t , cssLink , head ; if(QZFL.css.classFileNameCache[url]){ return; } if(typeof opts == "string"){ sid = opts; } opts = (typeof opts == "object") ? opts : {}; sid = opts.linkID || sid; doc = opts.doc || document; head = doc.getElementsByTagName("head")[0]; cssLink = ((t = doc.getElementById(sid)) && (t.nodeName == "LINK")) ? t : null; if (!cssLink) { cssLink = doc.createElement("link"); sid && (cssLink.id = sid); cssLink.rel = cssLink.rev = "stylesheet"; cssLink.type = "text/css"; cssLink.media = opts.media || "screen"; head.appendChild(cssLink); } try{ url && (cssLink.href = (url).replace(/^http:\/\//,window.location.protocol+'//')); }catch(ign){} QZFL.css.classFileNameCache[url] = true; return (QZFL.userAgent.ie < 9 && cssLink.sheet) || cssLink; //IE>=9开始支持 .sheet了,和 .styleSheet 相同 }, /** * 插入页面inline样式块 * @param {string} sheetId 样式表style Element的ID * @param {string} [rules=""] 样式表规则内容 * @returns {object} 返回样式表style Element对象 * @example QZFL.css.insertStyleSheet("cssid", "body {font-size: 75%;}"); */ insertStyleSheet: function(sheetId, rules){ var node = document.createElement("style"); node.type = 'text/css'; sheetId && (node.id = sheetId); document.getElementsByTagName("head")[0].appendChild(node); if (rules) { if (node.styleSheet) { node.styleSheet.cssText = rules; } else { node.appendChild(document.createTextNode(rules)); } } return node.sheet || node; }, /** * 删除一份样式表,包含内部style和外部css * @param {string|number} id 样式表的编号 * @deprecated 实用性不强,不适合在编程框架 * @example QZFL.css.removeStyleSheet("styleid"); */ removeStyleSheet: function(id){ var _ss = QZFL.css.getStyleSheetById(id); _ss && QZFL.dom.removeElement(_ss.owningElement || _ss.ownerNode); }, //下面很有用的一个正则,先静态化出来 _reClassToken: /\s+/, /** * 操作元素的className的核心方法,也可以直接调用,remove参数支持*通配符 * @param {object} elem 被操作的HTMLElement * @param {string} removeNames 要被取消的className们 * @param {string} addNames 要被加入的className们 * @returns {string} elem被操作后的className,若elem非法则为空串 */ updateClassName: function(elem, removeNames, addNames){ if (!elem || elem.nodeType != 1) { return ""; } var oriName = elem.className, _s = QZFL.css, ar, b; //受否有变化的flag if (removeNames && typeof(removeNames) == 'string' || addNames && typeof(addNames) == 'string') { if (removeNames == '*') { oriName = ''; } else { ar = oriName.split(_s._reClassToken); var i = 0, l = ar.length, n; //临时变量 oriName = {}; for (; i < l; ++i) { //将原始的className群结构化为表 ar[i] && (oriName[ar[i]] = true); } if (addNames) { //结构化addNames群,将该加入的加入到oriName群 ar = addNames.split(_s._reClassToken); l = ar.length; for (i = 0; i < l; ++i) { (n = ar[i]) && !oriName[n] && (b = oriName[n] = true); } } if (removeNames) { ar = removeNames.split(_s._reClassToken); l = ar.length; for (i = 0; i < l; i++) { (n = ar[i]) && oriName[n] && (b = true) && delete oriName[n]; } } } if (b) { ar.length = 0; for (var k in oriName) { //构造结果数组 ar.push(k); } oriName = ar.join(' '); elem.className = oriName; } } return oriName; }, /** * 某HTMLElement是否含有指定的样式类名称 * @param {object} elem 指定的HTML元素 * @param {string} name 指定的类名称 * @returns {boolean} 是否操作成功 * @example QZFL.css.hasClassName(document.getElementById("div_id"), "cname"); */ hasClassName: function(elem, name){ return (elem && name) ? (elem.classList ? elem.classList.contains(name) : (name && ((' ' + elem.className + ' ').indexOf(' ' + name + ' ') > -1)) ) : false; }, /** * 增加一组样式类名 * @param {object} elem 指定的HTML元素 * @param {string} names 指定的类名称 * @returns {string} 返回当前className * @example QZFL.css.addClassName(document.getElementById("ele"), "cname imname"); */ addClassName: function(elem, names){ var _s = QZFL.css; return names && ((elem && elem.classList && !_s._reClassToken.test(names)) ? elem.classList.add(names) : _s.updateClassName(elem, null, names)); }, /** * 除去一组样式类名 * @param {object} elem 指定的HTML元素 * @param {string} cname 指定的类名称 * @returns {string} 返回当前className * @example QZFL.css.removeClassName($("ele"),"cname"); */ removeClassName: function(elem, names){ var _s = QZFL.css; return names && ((elem && elem.classList && !_s._reClassToken.test(names)) ? elem.classList.remove(names) : _s.updateClassName(elem, names)); }, /** * 替换两种样式类名 * @param {object|object[]} elems 指定的HTML元素或者一个HTML元素集合 * @param {string} a 指定的类名称 * @param {string} b 指定的类名称 * @example QZFL.css.replaceClassName($("ele"), "sourceClass", "targetClass"); */ replaceClassName: function(elems, a, b){ QZFL.css.swapClassName(elems, a, b, true); }, /** * 交换两种样式类名 * @param {object|object[]} elems 指定的HTML元素或者一个HTML元素集合 * @param {string} a 指定的类名称 * @param {string} b 指定的类名称 * @param {boolean} _isRep 参数a,b是否反向可替换 * @example QZFL.css.swapClassName($("div_id"), "classone", "classtwo", true); */ swapClassName: function(elems, a, b, _isRep){ if (elems && typeof(elems) == "object") { if (elems.length === undefined) { elems = [elems]; } for (var elem, i = 0, l = elems.length; i < l; ++i) { if ((elem = elems[i]) && elem.nodeType == 1) { if (QZFL.css.hasClassName(elem, a)) { QZFL.css.updateClassName(elem, a, b); } else if (!_isRep && QZFL.css.hasClassName(elem, b)) { QZFL.css.updateClassName(elem, b, a); } } } } }, /** * 开关样式类名,调一次加上,再调一次干掉,或反之 * @param {object} elem 指定的HTML元素 * @param {string} name 指定的类名称 * @returns {undefined} * @example QZFL.css.toggleClassName($("ele"),"cname"); */ toggleClassName: function(elem, name){ if (!elem || elem.nodeType != 1) { return; } var _s = QZFL.css; if(elem.classList && name && !_s._reClassToken.test(name)){ return elem.classList.toggle(name); } if (_s.hasClassName(elem, name)) { _s.updateClassName(elem, name); } else { _s.updateClassName(elem, null, name); } } }; ///////////// //dom.js ///////////// /** * @fileoverview QZFL DOM 工具集,包含对浏览器DOM的一些操作 * @version $Rev: 1921 $ * @author QzoneWebGroup, ($LastChangedBy: ryanzhao $) - $Date: 2011-01-11 18:46:01 +0800 (周二, 11 一月 2011) $ */ /** * QZFL dom 接口封装对象。对浏览器常用的dom对象接口进行浏览器兼容封装 * * @namespace QZFL dom 接口封装对象 */ QZFL.dom = { /** * 根据id获取dom对象 * * @param {string} id 对象ID * @returns {object} 指定id的DOM节点,没有找到为null * @example QZFL.dom.getById("div_id"); */ getById : function(id) { return document.getElementById(id); }, /** * 根据name获取dom集合,有些标签例如li、span无法通过getElementsByName拿到,加上tagName指明就可以
<li name="n1">node1</li><span name="n1">node2</span> * ie只能获取到li,非ie下两者都可以 * * @param {string} name 所需节点的name * @param {string} [tagName=""] 标签名称tagName * @param {object} [rt=undefined] 查找的根对象 * @returns {object[]} 匹配到的节点集合 * @example QZFL.dom.getByName("div_name"); */ getByName : function(name, tagName, rt) { return QZFL.selector((tagName || "") + '[name="' + name + '"]', rt); }, /** * 获得制定节点 * * @param {string|object} e 包括id号,或则Html Element对象 * @returns {object} 匹配到的节点 * @example QZFL.dom.get("div_id"); */ get : function(e) { return (typeof(e) == "string") ? document.getElementById(e) : e; }, /** * 获得对象 * * @param {string|object} e 包括id号,或则HTML Node对象 * @returns {object} * @deprecated 这个太搞笑了,不要再用了 * @example QZFL.dom.getNode("div_id"); */ getNode : function(e) { return (e && (e.nodeType || e.item)) ? e : document.getElementById(e); }, /** * 删除节点 * * @param {string|object} el HTML元素的id或者HTML元素 * @example QZFL.dom.removeElement("div_id"); QZFL.dom.removeElement(QZFL.dom.get("div_id2")); */ removeElement : function(elem) { if (elem = QZFL.dom.get(elem)) { if(QZFL.userAgent.ie > 8 && elem.tagName == "SCRIPT"){ elem.src = ""; } elem.removeNode ? elem.removeNode(true) : (elem.parentNode && elem.parentNode.removeChild(elem)); } return elem = null; }, /** * 从以某元素开始,对指定元素属性的值使用传入的handler进行判断,handler返回true时查询停止,返回当前元素
否则以当前属性值所指的对象为根,递归重新查找,最终返回null * @param {object} elem HTML元素 * @param {string} prop 构成链的元素属性名 * @param {function} func 检查函数,返回true的时候当前查找终结, func = function(el){}; //传入当前的节点el * @returns {object} 结果对象,无结果时返回null * @example function getFirstChild(elem){ //获取第一个为HTMLElement的子节点 elem = QZFL.dom.get(elem); return QZFL.dom.searchChain(elem && elem.firstChild, 'nextSibling', function(el){ return el.nodeType == 1; }); } */ searchChain : function(elem, prop, func){ prop = prop || 'parentNode'; while (elem && elem.nodeType && elem.nodeType == 1) { if (!func || func.call(elem, elem)) { return elem; } elem = elem[prop]; } return null; }, /** * 通过当前节点不断往父级向上查找,直到找到含有指定className的dom节点 * * @param {string|object} el 对象id或则dom * @param {string} className css类名 * @deprecated 不建议使用了,请使用 {@link QZFl.element} * @returns {object} 第一个结果节点 */ searchElementByClassName : function(elem, className){ elem = QZFL.dom.get(elem); return QZFL.dom.searchChain(elem, 'parentNode', function(el){ return QZFL.css.hasClassName(el, className); }); }, /** * 获取指定className的所有子节点 * * @param {string} className 指定的class值 * @param {string} [tagName] 节点名 * @param {string|object} context 可能的根对象 * @deprecated 不建议使用了,请使用 {@link QZFl.element} * @returns {object[]} 结果节点集合 */ getElementsByClassName : function(className, tagName, context) { return QZFL.selector((tagName || '') + '.' + className, QZFL.dom.get(context)); }, /** * 判断指定的节点是否是第二个节点的祖先 * * @param {object} a 对象,父节点 * @param {object} b 对象,子孙节点 * @returns {boolean} true即b是a的子节点,否则为false * @example QZFL.dom.isAncestor(QZFL.dom.get("div1"), QZFL.dom.get("div2")) */ isAncestor : function(a, b) { return a && b && a != b && QZFL.dom.contains(a, b); }, /** * 根据函数得到特定的父节点 * * @param {object|string} node对象或其id * @param {string} method 创建对象的TagName * @returns {object} * @example var node = QZFL.dom.getAncestorBy($("div_id"), "div"); */ getAncestorBy : function(elem, method){ elem = QZFL.dom.get(elem); return QZFL.dom.searchChain(elem.parentNode, 'parentNode', function(el){ return el.nodeType == 1 && (!method || method(el)); }); }, /** * 得到第一个HTMLElement子节点 * * @param {object|string} HTMLElement对象或其id * @returns {object} 结果对象 * @example var element = QZFL.dom.getFirstChild("el_id"); */ getFirstChild : function(elem){ elem = QZFL.dom.get(elem); return elem.firstElementChild || QZFL.dom.searchChain( elem && elem.firstChild, 'nextSibling', function(el){ return el.nodeType == 1; } ); }, /** * 得到最后一个子HTMLElement节点 * * @param {object|string} node对象或其id * @returns {object} * @example var element = QZFL.dom.getFirstChild(QZFL.dom.get("el_id")); */ getLastChild : function(elem){ elem = QZFL.dom.get(elem); return elem.lastElementChild || QZFL.dom.searchChain( elem && elem.lastChild, 'previousSibling', function(el){ return el.nodeType == 1; } ); }, /** * 得到下一个兄HTMLElement弟节 * * @param {string|object} node对象或其id * @returns {object} * @example QZFL.dom.getNextSibling("el_id"); */ getNextSibling : function(elem){ elem = QZFL.dom.get(elem); return elem.nextElementSibling || QZFL.dom.searchChain( elem && elem.nextSibling, 'nextSibling', function(el){ return el.nodeType == 1; } ); }, /** * 得到上一个兄弟HTMLElement节点 * * @param {object|string} node对象或其id * @returns {object} * @example QZFL.dom.getPreviousSibling(QZFL.dom.get("el_id")); */ getPreviousSibling : function(elem){ elem = QZFL.dom.get(elem); return elem.previousElementSibling || QZFL.dom.searchChain( elem && elem.previousSibling, 'previousSibling', function(el){ return el.nodeType == 1; } ); }, /** * 交换两个节点 * * @param {object} node1 node对象 * @param {object} node2 node对象 * @example QZFL.dom.swapNode(QZFL.dom.get("el_one"),QZFL.dom.get("el_two")) */ swapNode : function(node1, node2) { // for ie if (node1.swapNode) { node1.swapNode(node2); } else { var prt = node2.parentNode, next = node2.nextSibling; if (next == node1) { prt.insertBefore(node1, node2); } else if (node2 == node1.nextSibling) { prt.insertBefore(node2, node1); } else { node1.parentNode.replaceChild(node2, node1); prt.insertBefore(node1, next); } } }, /** * 定点创建Dom对象,一句话把一个节点创建在另一个节点内,有点懒 * * @param {string} [tagName='div'] 创建对象的TagName * @param {string|object} [elem=document.body] 容器对象id或则dom * @param {boolean} [insertFirst=false] 是否从前部插入 * @param {object} [attrs=undefined] 对象属性列表,例如 {id:"newDom1",style:"color:#000"} * @example QZFL.dom.createElementIn("div",document.body,false,{id:"newDom1",style:"color:#000"}) * @returns {object} 返回创建好的dom引用 */ createElementIn : function(tagName, elem, insertFirst, attrs){ var _e = (elem = QZFL.dom.get(elem) || document.body).ownerDocument.createElement(tagName || "div"), k; // 设置Element属性 if (typeof(attrs) == 'object') { for (k in attrs) { if (k == "class") { _e.className = attrs[k]; } else if (k == "style") { _e.style.cssText = attrs[k]; } else { _e[k] = attrs[k]; } } } insertFirst ? elem.insertBefore(_e, elem.firstChild) : elem.appendChild(_e); return _e; }, /** * 获取对象渲染后的样式规则 * * @param {string|object} el 对象id或则dom * @param {string} property 样式规则名,请使用js语法,如z-index对应的是zIndex * @example var width=QZFL.dom.getStyle("div_id","width");//width=163px; * @returns {string} 样式值 */ getStyle : function(el, property) { el = QZFL.dom.get(el); if (!el || el.nodeType == 9) { return null; } var w3cMode = document.defaultView && document.defaultView.getComputedStyle, computed = !w3cMode ? null : document.defaultView.getComputedStyle(el, ''), value = ""; switch (property) { case "float" : property = w3cMode ? "cssFloat" : "styleFloat"; break; case "opacity" : if (!w3cMode) { // IE Mode var val = 100; try { val = el.filters['DXImageTransform.Microsoft.Alpha'].opacity; } catch (e) { try { val = el.filters('alpha').opacity; } catch (e) {} } return val / 100; }else{ return parseFloat((computed || el.style)[property]); } break; case "backgroundPositionX" : // 只有ie和webkit浏览器支持 // background-position-x if (w3cMode) { property = "backgroundPosition"; return ((computed || el.style)[property]).split(" ")[0]; } break; case "backgroundPositionY" : // 只有ie和webkit浏览器支持 // background-position-y if (w3cMode) { property = "backgroundPosition"; return ((computed || el.style)[property]).split(" ")[1]; } break; } if (w3cMode) { return (computed || el.style)[property]; } else { return (el.currentStyle[property] || el.style[property]); } }, /** * 设置样式规则 * * @param {string|object} el 对象id或则dom * @param {string|object} properties 样式规则表,如{zIndex:10000, height:"200px"},或单个字符串样式名 * @param {string|number} [value] 若上一个参数是字符串形式的样式名,这里给出样式值 * @example
QZFL.dom.setStyle("div_id", "width", "200px");
QZFL.dom.setStyle("div_id", {"width" : "200px", "height" : "300px"});
* @returns {boolean} 成功返回true */ setStyle : function(el, properties, value) { var DOM = QZFL.dom; if (!(el = DOM.get(el)) || el.nodeType != 1) { return false; } var tmp, bRtn = true, re; if (typeof(properties) == 'string') { tmp = properties; properties = {}; properties[tmp] = value; } for (var prop in properties) { value = properties[prop]; re = DOM.convertStyle(el, prop, value); prop = re.prop; value = re.value; if (typeof el.style[prop] != "undefined") { el.style[prop] = value; bRtn = bRtn && true; } else { bRtn = bRtn && false; } } return bRtn; }, /** * 转换属性和值 */ convertStyle : function(el, prop, value){ var DOM = QZFL.dom, tmp, rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, w3cMode; w3cMode = ((tmp = document.defaultView) && tmp.getComputedStyle); if (prop == 'float') { prop = w3cMode ? "cssFloat" : "styleFloat"; } else if (prop == 'opacity') { if (!w3cMode) { // for ie only prop = 'filter'; value = value >= 1 ? '' : ('alpha(opacity=' + Math.round(value * 100) + ')'); } } else if (prop == 'backgroundPositionX' || prop == 'backgroundPositionY') { tmp = prop.slice(-1) == 'X' ? 'Y' : 'X'; if (w3cMode) { var v = QZFL.dom.getStyle(el, "backgroundPosition" + tmp); prop = 'backgroundPosition'; typeof(value) == 'number' && (value = value + 'px'); value = tmp == 'Y' ? (value + " " + (v || "top")) : ((v || 'left') + " " + value); } } value += (typeof value === "number" && !rexclude.test(prop) ? 'px' : ''); return { 'prop' : prop, 'value' : value }; }, /** * 建立有name属性的element * * @param {string} type node的tagName * @param {string} name name属性值 * @param {object} [doc=document] 所在文档树 * @returns {object} 结果element * @example QZFL.dom.createNamedElement("div","div_name",QZFL.dom.get("doc")); */ createNamedElement : function(type, name, doc) { var _doc = doc || document, element; try { element = _doc.createElement('<' + type + ' name="' + name + '">'); } catch (ign) {} if (!element) { element = _doc.createElement(type); } if (!element.name) { element.name = name; } return element; }, /** * 获取节点矩形说明符 * @param {object} elem * @returns {object} 返回位置说明对象 {"top","left","width","height"} */ getRect : function(elem){ if (elem = QZFL.dom.get(elem)) { var box = QZFL.object.extend({}, elem.getBoundingClientRect()); if (typeof box.width == 'undefined') { box.width = box.right - box.left; box.height = box.bottom - box.top; } return box; } }, /** * 获取对象坐标和尺寸 * * @param {object} elem * @returns {object} 返回位置说明对象 {"top","left","width","height"}; * @example var position = QZFL.dom.getPosition(QZFL.dom.get("div_id")); */ getPosition : function(elem){ var box, s, doc; if (box = QZFL.dom.getRect(elem)) { if (s = QZFL.dom.getScrollLeft(doc = elem.ownerDocument)) { box.left += s, box.right += s; } if (s = QZFL.dom.getScrollTop(doc)) { box.top += s, box.bottom += s; } return box; } }, /** * 设置对象坐标和尺寸 * * @param {object} el * @param {object} pos 位置和大小描述对象 * @example QZFL.dom.setPosition(QZFL.dom.get("div_id"),{"100px","100px","400px","300px"}); */ setPosition : function(el, pos) { QZFL.dom.setXY(el, pos['left'], pos['top']); QZFL.dom.setSize(el, pos['width'], pos['height']); }, /** * 获取对象坐标 * * @param {object} elem * @returns {object} 数组结构 [top值, left值] * @example var xy=QZFL.dom.getXY(QZFL.dom.get("div_id")); */ getXY : function(elem){ var box = QZFL.dom.getPosition(elem) || { left: 0, top: 0 }; return [box.left, box.top]; }, /** * 获取对象尺寸 * * @param {object} elem * @returns {object} [width值, height值] * @example var size = QZFL.dom.getSize(QZFL.dom.get("div_id")); */ getSize : function(elem){ var box = QZFL.dom.getPosition(elem) || { width: -1, height: -1 }; return [box.width, box.height]; }, /** * 设置dom坐标 * * @param {object} elem * @param {string|number} x 横坐标 * @param {string|number} y 纵坐标 * @example QZFL.dom.setXY(QZFL.dom.get("div_id"),400,200); */ setXY : function(elem, x, y){ var _ml = parseInt(QZFL.dom.getStyle(elem, "marginLeft")) || 0, _mt = parseInt(QZFL.dom.getStyle(elem, "marginTop")) || 0; QZFL.dom.setStyle(elem, { left: ((parseInt(x, 10) || 0) - _ml) + "px", top: ((parseInt(y, 10) || 0) - _mt) + "px" }); }, /** * 获取对象scrollLeft的值 * * @param {object} [doc=document] 所需检查的页面document引用 * @returns {number} * @example QZFL.dom.getScrollLeft(document); */ getScrollLeft : function(doc) { var _doc = doc || document; return (_doc.defaultView && _doc.defaultView.pageXOffset) || Math.max(_doc.documentElement.scrollLeft, _doc.body.scrollLeft); }, /** * 获取对象的scrollTop的值 * * @param {object} [doc=document] 所需检查的页面document引用 * @returns {number} * @example QZFL.dom.getScrollTop(document); */ getScrollTop : function(doc) { var _doc = doc || document; return (_doc.defaultView && _doc.defaultView.pageYOffset) || Math.max(_doc.documentElement.scrollTop, _doc.body.scrollTop); }, /** * 获取对象scrollHeight的值 * * @param {object} [doc=document] 所需检查的页面document引用 * @returns {number} * @example QZFL.dom.getScrollHeight(document); */ getScrollHeight : function(doc) { var _doc = doc || document; return Math.max(_doc.documentElement.scrollHeight, _doc.body.scrollHeight); }, /** * 获取对象的scrollWidth的值 * * @param {object} [doc=document] 所需检查的页面document引用 * @returns {number} * @example QZFL.dom.getScrollWidht(document); */ getScrollWidth : function(doc) { var _doc = doc || document; return Math.max(_doc.documentElement.scrollWidth, _doc.body.scrollWidth); }, /** * 设置对象scrollLeft的值 * * @param {number} value scroll left的修改值 * @param {object} [doc=document] 所需检查的页面document引用 * @example QZFL.dom.setScrollLeft(200,document); */ setScrollLeft : function(value, doc) { var _doc = doc || document; _doc[_doc.compatMode == "CSS1Compat" && !QZFL.userAgent.webkit ? "documentElement" : "body"].scrollLeft = value; }, /** * 设置对象的scrollTop的值 * * @param {number} value scroll top的修改值 * @param {object} [doc=document] 所需检查的页面document引用 * @example QZFL.dom.setScrollTop(200,document); */ setScrollTop : function(value, doc) { var _doc = doc || document; _doc[_doc.compatMode == "CSS1Compat" && !QZFL.userAgent.webkit ? "documentElement" : "body"].scrollTop = value; }, /** * 获取对象的可视区域高度 * * @param {object} [doc=document] 所需检查的页面document引用 * @returns {number} * @example QZFL.dom.getClientHeight(); */ getClientHeight : function(doc) { var _doc = doc || document; return _doc.compatMode == "CSS1Compat" ? _doc.documentElement.clientHeight : _doc.body.clientHeight; }, /** * 获取对象的可视区域宽度 * * @param {object} [doc=document] 所需检查的页面document引用 * @returns {number} * @example QZFL.dom.getClientWidth(); */ getClientWidth : function(doc) { var _doc = doc || document; return _doc.compatMode == "CSS1Compat" ? _doc.documentElement.clientWidth : _doc.body.clientWidth; }, /** * size数值需要用的模式 * @private * */ _SET_SIZE_RE : /^\d+(?:\.\d*)?(px|%|em|in|cm|mm|pc|pt)?$/, /** * 设置dom尺寸 * * @param {string|object} el 节点ID或者节点本身引用 * @param {string|number} width 宽度 * @param {string|number} height 高度 * @example QZFL.dom.setSize($("abc"), 100, 200); */ setSize : function(el, w, h){ el = QZFL.dom.get(el); var _r = QZFL.dom._SET_SIZE_RE, m; QZFL.dom.setStyle(el, "width", (m=_r.exec(w)) ? (m[1] ? w : (parseInt(w,10)+'px')) : 'auto'); QZFL.dom.setStyle(el, "height",(m=_r.exec(h)) ? (m[1] ? h : (parseInt(h,10)+'px')) : 'auto'); }, /** * 获取document的window对象 * * @param {object} [doc=document] 所需检查的页面document引用 * @returns {object} 返回结果window对象 * @example QZFL.dom.getDocumentWindow(); */ getDocumentWindow : function(doc) { var _doc = doc || document; return _doc.parentWindow || _doc.defaultView; }, /** * 按Tagname获取指定命名空间的节点 * * @param {object} [node=document] 所需遍历的根节点 * @param {string} ns 命名空间名 * @param {string} tgn 标签名 * @returns {object} 结果数组 * @example QZFL.dom.getElementsByTagNameNS(document, "qz", "div"); */ getElementsByTagNameNS : function(node, ns, tgn) { node = node || document; var res = []; if (node.getElementsByTagNameNS) { return node.getElementsByTagName(ns + ":" + tgn); } else if (node.getElementsByTagName) { var n = document.namespaces; if (n.length > 0) { var l = node.getElementsByTagName(tgn); for (var i = 0, len = l.length; i < len; ++i) { if (l[i].scopeName == ns) { res.push(l[i]); } } } } return res; }, /** * 从一个给出节点向上寻找一个tagName相符的节点 * * @param {object} elem 给出的节点 * @param {string} tn 需要查找的节点tag name * @returns {object} 结果,没找到是null * @example QZFL.dom.getElementByTagNameBubble(QZFL.dom.get("div_id"),"div"); */ getElementByTagNameBubble : function(elem, tn){ if(!tn){ return null; } var maxLv = 15; tn = String(tn).toUpperCase(); if(tn == 'BODY'){ return document.body; } elem = QZFL.dom.searchChain( elem = QZFL.dom.get(elem), 'parentNode', function(el){ return el.tagName == tn || el.tagName == 'BODY' || (--maxLv) < 0; } ); return !elem || maxLv < 0 ? null : elem; }, /** * 在元素相邻的位置(具体位置可选)插入 html文本 text纯文本 element节点 * @param {object} elem 元素引用 * @param {number} where 取值0 1 2 3,分别对应:beforeBegin, afterBegin, beforeEnd, afterEnd * @param {object|string} html html文本 或 text普通文本 或 element节点引用 * @param {boolean} [isText=false] 当需要插入text时,用此参数区别于html * @returns {boolean} 操作是否成功 * @example QZFL.dom.insertAdjacent($("test"), 1, "world!", true); //0 1 2 3 分别代表:节点外节点前;节点内头部;节点内尾部;节点外节点后 */ insertAdjacent : function(elem, where, html, isText){ var range, pos = ['beforeBegin', 'afterBegin', 'beforeEnd', 'afterEnd'], doc; if (QZFL.lang.isElement(elem) && pos[where] && (QZFL.lang.isString(html) || QZFL.lang.isElement(html))) { if (elem.insertAdjacentHTML && elem.insertAdjacentElement && elem.insertAdjacentText) { elem['insertAdjacent' + (typeof(html) == 'object' ? 'Element' : (isText ? 'Text' : 'HTML'))](pos[where], html); } else { range = (doc = elem.ownerDocument).createRange(); range[where == 1 || where == 2 ? 'selectNodeContents' : 'selectNode'](elem); range.collapse(where < 2); range.insertNode(typeof(html) != 'string' ? html : isText ? doc.createTextNode(html) : range.createContextualFragment(html)); } return true; } return false; } }; ///////////// //event.js ///////////// /** * @fileoverview QZFL 事件驱动器,给浏览器提供基本的事件驱动接口 * @version 1.$Rev: 1921 $ * @author QzoneWebGroup, ($LastChangedBy: ryanzhao $) * @lastUpdate $Date: 2011-01-11 18:46:01 +0800 (周二, 11 一月 2011) $ */ /** * 事件驱动对象,包含许多事件驱动以及绑定等方法,关键 * * @namespace QZFL 事件驱动器,给浏览器提供基本的事件驱动接口 */ QZFL.event = { /** * 按键代码映射 * * @namespace QZFL.event.KEYS 里面包含了对按键的映射 * @type Object */ KEYS : { /** * 退格键 */ BACKSPACE : 8, /** * tab */ TAB : 9, RETURN : 13, ESC : 27, SPACE : 32, LEFT : 37, UP : 38, RIGHT : 39, DOWN : 40, DELETE : 46 }, //这个东东不需要了吧 /** * 扩展类型,这类事件在绑定的时候允许传参数,并且用来特殊处理一些特别的事件绑定 * * @ignore * extendType : /(click|mousedown|mouseover|mouseout|mouseup|mousemove|scroll|contextmenu|resize)/i,*/ /** * 全局事件树 * @ignore */ _eventListDictionary : {}, /** * @ignore */ _fnSeqUID : 0, /** * @ignore */ _objSeqUID : 0, /** * 事件绑定 * * @param {DocumentElement} obj 需要添加事件的页面对象 * @param {String} eventType 需要添加的事件 * @param {Function} fn 事件需要绑定到的处理函数 * @param {Array} argArray 参数数组 * @type Boolean * @version 1.1 memory leak optimise by scorr * @author zishunchen * @return 是否绑定成功(true为成功,false为失败) * @example QZFL.event.addEvent(QZFL.dom.get('demo'),'click',hello); */ addEvent : function(obj, eventType, fn, argArray) { var cfn, res = false, l, handlers, efn, sTime; if (!obj) { return res; } if (!obj.eventsListUID) { obj.eventsListUID = "e" + (++QZFL.event._objSeqUID); } if (!(l = QZFL.event._eventListDictionary[obj.eventsListUID])) { l = QZFL.event._eventListDictionary[obj.eventsListUID] = {}; } if (!fn.__elUID) { fn.__elUID = "e" + (++QZFL.event._fnSeqUID) + obj.eventsListUID; } //插入ipad设备上mouseover和mouseout的兼容 if(QZFL.userAgent.isiPad && ((eventType == 'mouseover') || (eventType == 'mouseout'))){ cfn = function(evt){ sTime = new Date().getTime(); } l['_'+eventType] = fn; if(l._ipadBind){ return false; } eventType = 'touchstart'; l._ipadBind = 1; efn = function(evt){ var t = new Date().getTime() - sTime,fn; if(t < 700){//mouseover或者out fn = l._mouseover; if(l._ismouseover){ fn = l._mouseout; l._ismouseover = 0 }else{ l._ismouseover = 1; } QZFL.event.preventDefault(evt); return fn && fn.apply(obj, !argArray ? [QZFL.event.getEvent(evt)] : ([QZFL.event.getEvent(evt)]).concat(argArray)); }//其他的为click return true; } QZFL.event.addEvent(obj, 'touchend', efn); } //兼容end if (!l[eventType]) { l[eventType] = {}; } if (!l[eventType].handlers) { l[eventType].handlers = {}; } handlers = l[eventType].handlers; if(typeof(handlers[fn.__elUID]) == 'function'){ return false; } cfn = cfn || function(evt) { return fn.apply(obj, !argArray ? [QZFL.event.getEvent(evt)] : ([QZFL.event.getEvent(evt)]).concat(argArray)); }; if (obj.addEventListener) { obj.addEventListener(eventType, cfn, false); res = true; } else if (obj.attachEvent) { res = obj.attachEvent("on" + eventType, cfn); } else { res = false; } if (res) { handlers[fn.__elUID] = cfn; } return res; }, /** * 手动触发回调 * @param {HTMLElement} obj 触发的节点 * @param {String} eventType 事件类型 */ trigger : function(obj, eventType){ var l = obj && QZFL.event._eventListDictionary[obj.eventsListUID], handlers = l && l[eventType] && l[eventType].handlers, i; if(handlers){ try{ for(i in handlers){ handlers[i].call(window, {}); } }catch(evt){QZFL.console.print('QZFL.event.trigger error')} } }, /** * 方法取消绑定 * * @param {DocumentElement} obj 需要取消事件绑定的页面对象 * @param {String} eventType 需要取消绑定的事件 * @param {Function} fn 需要取消绑定的函数 * @return 是否成功取消(true为成功,false为失败) * @type Boolean * @version 1.1 memory leak optimise by scorr * @author zishunchen * @example QZFL.event.removeEvent(QZFL.dom.get('demo'),'click',hello); */ removeEvent : function(obj, eventType, fn) { var cfn = fn, res = false, l = QZFL.event._eventListDictionary, r; if (!obj) { return res; } if (!fn) { return QZFL.event.purgeEvent(obj, eventType); } if (obj.eventsListUID && l[obj.eventsListUID] && l[obj.eventsListUID][eventType]) { l = l[obj.eventsListUID][eventType].handlers; if(l && l[fn.__elUID]){ cfn = l[fn.__elUID]; r = l; } } if (obj.removeEventListener) { obj.removeEventListener(eventType, cfn, false); res = true; } else if (obj.detachEvent) { obj.detachEvent("on" + eventType, cfn); res = true; } else { //rt.error("Error.!."); return false; } if (res && r && r[fn.__elUID]) { delete r[fn.__elUID]; } return res; }, /** * 取消全部某类型的方法绑定 * * @param {DocumentElement} obj 需要取消事件绑定的页面对象 * @param {String} eventType 需要取消绑定的事件 * @example QZFL.event.purgeEvent(QZFL.dom.get('demo'),'click'); * @return {Boolean} 是否成功取消(true为成功,false为失败) */ purgeEvent : function(obj, type) { var l, h; if (obj.eventsListUID && (l = QZFL.event._eventListDictionary[obj.eventsListUID]) && l[type] && (h = l[type].handlers)) { for (var k in h) { if (obj.removeEventListener) { obj.removeEventListener(type, h[k], false); } else if (obj.detachEvent) { obj.detachEvent('on' + type, h[k]); } } } if (obj['on' + type]) { obj['on' + type] = null; } if (h) { l[type].handlers = null; delete l[type].handlers; } return true; }, /** * 根据不同浏览器获取对应的Event对象 * * @param {Event} evt * @return 修正过的Event对象, 同时返回一个修正button的自定义属性; * @type Event * @example QZFL.event.getEvent(); * @return Event */ getEvent: function(evt) { var evt = window.event || evt || null, c, _s = QZFL.event.getEvent, ct = 0; if(!evt){ c = arguments.callee; while(c && ct < _s.MAX_LEVEL){ if(c.arguments && (evt = c.arguments[0]) && (typeof(evt.button) != "undefined" && typeof(evt.ctrlKey) != "undefined")){ break; } ++ct; c = c.caller; } } return evt; }, /** * 获得鼠标按键 * * @param {Object} evt * @example QZFL.event.getButton(evt); * @return {number} 鼠标按键 -1=无法获取event 0=左键 1= 中键 2= 右键 */ getButton : function(evt) { var e = QZFL.event.getEvent(evt); if (!e) { return -1 } if (QZFL.userAgent.ie) { return e.button - Math.ceil(e.button / 2); } else { return e.button; } }, /** * 返回事件触发的对象 * * @param {Object} evt * @example QZFL.event.getTarget(evt); * @return {object} */ getTarget : function(evt) { var e = QZFL.event.getEvent(evt); if (e) { return e.srcElement || e.target; } else { return null; } }, /** * 返回获得焦点的对象 * * @param {Object} evt * @example QZFL.event.getCurrentTarget(); * @return {object} */ getCurrentTarget : function(evt) { var e = QZFL.event.getEvent(evt); if (e) { /** * @default document.activeElement */ return e.currentTarget || document.activeElement; } else { return null; } }, /** * 禁止事件冒泡传播 * * @param {Event} evt 事件,非必要参数 * @example QZFL.event.cancelBubble(); */ cancelBubble : function(evt) { evt = QZFL.event.getEvent(evt); if (!evt) { return false } if (evt.stopPropagation) { evt.stopPropagation(); } else { if (!evt.cancelBubble) { evt.cancelBubble = true; } } }, /** * 取消浏览器的默认事件 * * @param {Event} evt 事件,非必要参数 * @example QZFL.event.preventDefault(); */ preventDefault : function(evt) { evt = QZFL.event.getEvent(evt); if (!evt) { return false } if (evt.preventDefault) { evt.preventDefault(); } else { evt.returnValue = false; } }, /** * 获取事件触发时的鼠标位置x * * @param {Object} evt 事件对象引用 * @example QZFL.event.mouseX(); */ mouseX : function(evt) { evt = QZFL.event.getEvent(evt); return evt.pageX || (evt.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)); }, /** * 获取事件触发时的鼠标位置y * * @param {Object} evt 事件对象引用 * @example QZFL.event.mouseX(); */ mouseY : function(evt) { evt = QZFL.event.getEvent(evt); return evt.pageY || (evt.clientY + (document.documentElement.scrollTop || document.body.scrollTop)); }, /** * 获取事件RelatedTarget * @param {Object} evt 事件对象引用 * @example QZFL.event.getRelatedTarget(); */ getRelatedTarget: function(ev) { ev = QZFL.event.getEvent(ev); var t = ev.relatedTarget; if (!t) { if (ev.type == "mouseout") { t = ev.toElement; } else if (ev.type == "mouseover") { t = ev.fromElement; } else { } } return t; }, /** * 全局页面加载完成后的事件回调 * @param {function} fn 回调接口 * @deprecated */ onDomReady:function(fn){ var _s = QZFL.event.onDomReady; QZFL.event._bindReady(); _s.pool.push(fn); }, _bindReady:function(){ var _s = QZFL.event.onDomReady; if(typeof _s.pool!='undefined'){//已经绑定了监听函数,不用再次绑定 return; } _s.pool = _s.pool || []; if(document.readyState === "complete"){ return setTimeout(QZFL.event._readyFn, 1); } if(document.addEventListener){//Chrome Safari Firefox document.addEventListener("DOMContentLoaded",QZFL.event._domReady, false ); window.addEventListener("load",QZFL.event._readyFn,false); }else if(document.attachEvent){//ie document.attachEvent("onreadystatechange",QZFL.event._domReady); window.attachEvent("onload",QZFL.event._readyFn); var toplevel = false; try{ toplevel = window.frameElement == null; }catch(e){} if(document.documentElement.doScroll && toplevel){ QZFL.event._ieScrollCheck(); } } }, _readyFn : function(){ var _s = QZFL.event.onDomReady; _s.isReady = true; while(_s.pool.length) { var fn = _s.pool.shift(); QZFL.lang.isFunction(fn) && fn(); } _s.pool.length == 0 && (_s._fn = null); }, _domReady : function(){ if(document.addEventListener){ document.removeEventListener("DOMContentLoaded",QZFL.event._domReady,false); QZFL.event._readyFn(); }else if(document.attachEvent){ if(document.readyState === "complete"){ document.detachEvent( "onreadystatechange",QZFL.event._domReady); QZFL.event._readyFn(); } } }, // The DOM ready check for IE _ieScrollCheck : function() { if(QZFL.event.onDomReady.isReady){ return; } try{ document.documentElement.doScroll("left"); }catch(e){ setTimeout(QZFL.event._ieScrollCheck, 1 ); return; } QZFL.event._readyFn(); }, /** * @description 代理事件函数,第一次使用为异步过程 * @param {HTMLElement} delegateDom 代理节点 * @param {String} selector 目标选择器 * @param {String} eventType 事件类型 * @param {Function} fn 事件函数 * @param {Array} [argsArray] 参数数组 * @example * QZFL.event.delegate($('container'), '.namecard', 'mouseenter', function(){}); //代理事件 */ delegate : function(delegateDom, selector, eventType, fn, argsArray) { var eventData, handler, handlerObj, handlerArray, delegateType, res = false, E = QZFL.event; //pre condition if(!delegateDom || !selector || !eventType || !fn) { return res; } //init data if (!delegateDom.eventsListUID) { delegateDom.eventsListUID = "e" + (++E._objSeqUID); } if (!(eventData = E._eventListDictionary[delegateDom.eventsListUID])) { eventData = E._eventListDictionary[delegateDom.eventsListUID] = {}; } if (!fn.__elUID) { fn.__elUID = "e" + (++E._fnSeqUID) + delegateDom.eventsListUID; } //初始化事件类型 delegateType = (E.delegate._specialEvent[eventType] || {}).delegateType || eventType; if (!eventData[delegateType]) { eventData[delegateType] = {}; } handler = eventData.delegateHandler; if(!handler) { //单事件注册 handler = eventData.delegateHandler = function(e) { E.delegate._dispatch.apply(delegateDom, arguments); }; } //初始化事件 - 对于一个代理对象,一种事件类型,仅注册一次事件 handlerArray = eventData[delegateType].delegateHandlers; if(!handlerArray) { handlerArray = eventData[delegateType].delegateHandlers = []; eventData.delegateCount = (eventData.delegateCount || 0) + 1; //注册事件 if(delegateDom.addEventListener) { delegateDom.addEventListener(delegateType, handler, false); res = true; }else if(delegateDom.attachEvent) { delegateDom.attachEvent('on' + delegateType, handler); res = true; }else{ return res; } }else{ //避免重复注册 for(var i = 0, len = handlerArray.length; i < len; i++){ if(handlerArray[i].guid === fn.__elUID){ return false; } } res = true; } //一个数据结构 handlerObj = { 'selector' : selector, 'guid' : fn.__elUID, 'handler' : fn, 'delegateType' : delegateType, 'argsArray' : argsArray, 'origType' : eventType, 'quick' : E.delegate._quickParse(selector) } //store handlerArray.push(handlerObj); return res; }, /** * @description 取消事件代理 * @param {HTMLElement} delegateDom 取消事件代理的节点 * @param {String} [selector] 选择器 * @param {String} [eventType] 事件类型 * @param {Function} [fn] 回调函数 * @example * QZFL.event.undelegate($('container')); //取消节点的所有delegate事件 * QZFL.event.undelegate($('container'), 'click'); //取消节点的click delegate事件 * QZFL.event.undelegate($('container'), '.namecard', 'click', fn); //取消指定的delegate事件 */ undelegate : function(delegateDom, selector, eventType, fn) { var eventData, handlerArray, delegateType, E = QZFL.event, len; //取出基本数据 eventData = E._eventListDictionary[(delegateDom || {}).eventsListUID]; if(!eventData) { return; } if(arguments.length === 2) { eventType = selector; selector == ''; } if(!eventType) { for(var j in eventData) { arguments.callee(delegateDom, selector, j, fn); } return; } eventType = (E.delegate._specialEvent[eventType] || {}).delegateType || eventType; handlerArray = (eventData[eventType] || {}).delegateHandlers; if(!handlerArray){ return; } len = handlerArray.length; if(fn || selector) { for(var i = 0, h; i < handlerArray.length;) { h = handlerArray[i]; if((typeof(fn) == 'function' && h.guid === fn.__elUID) || (selector === h.selector)) { handlerArray.splice(i, 1); }else{ i++; } } }else{ handlerArray.length = 0; //清除数据 } //clear if(handlerArray.length === 0 && len !== 0) { delegateType = (E.delegate._specialEvent[eventType] || {}).delegateType || eventType; if(delegateDom.removeEventListener) { delegateDom.removeEventListener(delegateType, eventData.delegateHandler, false); } else if(delegateDom.detachEvent) { delegateDom.detachEvent('on' + delegateType, eventData.delegateHandler); } handlerArray = null; delete eventData[eventType].delegateHandlers; eventData.delegateCount--; if(eventData.delegateCount === 0){ delete eventData.delegateHandler; delete eventData.delegateCount; } } } }; /** * 方法同 QZFL.event.addEvent * * @see QZFL.event.addEvent */ QZFL.event.on = QZFL.event.addEvent; /** * 方法同 QZFL.object.bind * * @see QZFL.object.bind */ QZFL.event.bind = QZFL.object.bind; /** * getEvent方法的最深递归查询层次 * @ignore */ QZFL.event.getEvent.MAX_LEVEL = 10; QZFL.event.delegate._quickParse = function(selector) { var REG = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, //[all, tag, id, class] quick = REG.exec(selector); if(quick) { quick[1] = (quick[1] || "").toLowerCase(); quick[3] = quick[3] && new RegExp("(?:^|\\s)" + quick[3] + "(?:\\s|$)"); } return quick; }; QZFL.event.delegate._isQuickMatch = function(elem, m) { return ( (!m[1] || elem.nodeName.toLowerCase() === m[1]) && (!m[2] || elem.id === m[2]) && (!m[3] || m[3].test(elem.className)) ); }; QZFL.event.delegate._specialEvent = {}; QZFL.object.each({ 'mouseenter' : 'mouseover', 'mouseleave' : 'mouseout' }, function(delegateType, origType) { QZFL.event.delegate._specialEvent[origType] = { 'delegateType' : delegateType, 'handler' : function(event, handlerObj) { var target = this, relatedTarget = QZFL.event.getRelatedTarget(event); if(target !== relatedTarget && !QZFL.dom.isAncestor(target, relatedTarget)) { handlerObj.handler.apply(this, [event].concat(handlerObj.argsArray)); } } } }); QZFL.event.delegate._dispatch = function(event) { var E = QZFL.event, event = E.getEvent(event), type = event.type, eventData, handlerArray, hit, curDom, specialHandler, selector; eventData = E._eventListDictionary[this.eventsListUID] || {}; handlerArray = (eventData[type] || {}).delegateHandlers || []; for(curDom = E.getTarget(event); curDom != this; curDom = curDom.parentNode || this) { for(var i = 0, len = handlerArray.length, handlerObj; i < len; i++) { handlerObj = handlerArray[i]; selector = handlerObj.selector; hit = (handlerObj.quick ? E.delegate._isQuickMatch(curDom, handlerObj.quick) : (Sizzle && Sizzle.matchesSelector(curDom, selector))); if(hit) { specialHandler = (E.delegate._specialEvent[handlerObj.origType] || {}).handler; //fire if(specialHandler){ specialHandler.apply(curDom, [event, handlerObj]); }else{ handlerObj.handler.apply(curDom, [event].concat(handlerObj.argsArray)); } } } } }; ///////////// //queue.js ///////////// /** * @fileoverview QZFL 函数队列系统,可以把一系列函数作为队列并且按顺序执行。在执行过程中函数出现的错误不会影响到下一个队列进程 * @version 1.$Rev: 1921 $ * @author QzoneWebGroup, ($LastChangedBy: ryanzhao $) * @lastUpdate $Date: 2011-01-11 18:46:01 +0800 (周二, 11 一月 2011) $ */ /** * 函数队列引擎 * * @param {string} key 队列名称 * @param {array} queue 队列函数数组 * @example QZFL.queue("test",[function(){alert(d)},function(){alert(2)}]); * QZFL.queue.run("test"); * * @namespace QZFL 队列引擎,给函数提供批量的队列执行方法 * @return {Queue} 返回队列系统构造对象 */ QZFL.queue = (function(){ var _o = QZFL.object; var _queue = {}; var _Queue = function(key,queue){ if (this instanceof arguments.callee) { this._qz_queuekey = key; return this; } if (_o.getType(queue = queue || []) == "array"){ _queue[key] = queue; } return new _Queue(key); }; var _extend = /**@lends QZFL.queue*/{ /** * 往一个队列里插入一个新的函数 * * @param {string|function} key 队列名称 当作为构造函数时则只需要直接传 * @param {function} fn 可执行的函数 * @example QZFL.queue("test"); * QZFL.queue.push("test",function(){alert("ok")}); * // 或者 * QZFL.queue("test").push(function(){alert("ok")}); */ push : function(key,fn){ fn = this._qz_queuekey?key:fn; _queue[this._qz_queuekey || key].push(fn); }, /** * 从队列里去除第一个函数,并且执行一次 * * @param {string} key 队列名称 * @example QZFL.queue("test",[function(){alert("ok")}]); * QZFL.queue.shift("test"); * // 或者 * QZFL.queue("test",[function(){alert("ok")}]).shift(); * @return 返回第一个队列函数执行的结果 */ shift : function(key) { var _q = _queue[this._qz_queuekey || key]; if (_q) { return QZFL.queue._exec(_q.shift()); } }, /** * 返回队列长度 * @param {string} key 队列名称 * * @example QZFL.queue("test",[function(){alert("ok")}]); * QZFL.queue.getLen("test"); * // 或者 * QZFL.queue("test",[function(){alert("ok")}]).getLen(); * * @return 返回第一个队列函数执行的结果 */ getLen: function(key){ return _queue[this._qz_queuekey || key].length; }, /** * 执行队列 * * @param {string} key 队列名称 * @example QZFL.queue("test",[function(){alert("ok")}]); * QZFL.queue.run("test"); * // 或者 * QZFL.queue("test",[function(){alert("ok")}]).run(); */ run : function(key){ var _q = _queue[this._qz_queuekey || key]; if (_q) { _o.each(_q,QZFL.queue._exec); } }, /** * 分时执行队列 * * @param {string} key 队列名称 * @param {object} conf 可选参数 默认值为{'run': 100, 'wait': 50};每次运行100ms,暂停50ms再继续运行队列,直至队列为空 * @example QZFL.queue("test",[function(){alert("1")},function(){alert("2")},function(){alert("3")}]); * QZFL.queue.timedChunk("test", {'runTime': 1000, 'waitTime': 40, 'onRunEnd': function(){alert('allRuned');}, 'onWait': function(){alert('wait');}}); * */ timedChunk : function(key, conf){ var _q = _queue[this._qz_queuekey || key], _conf; if (_q) { //合并用户传入的参数和默认参数 _conf = QZFL.lang.propertieCopy(conf, QZFL.queue._tcCof, null, true); setTimeout(function(){ var _start = +new Date(); do { QZFL.queue.shift(key); } while (QZFL.queue.getLen(key) > 0 && (+new Date() - _start < _conf.runTime)); if (QZFL.queue.getLen(key) > 0){ setTimeout(arguments.callee, _conf.waitTime); _conf.onWait(); } else { _conf.onRunEnd(); } }, 0); } }, /** * 分时执行队列的默认参数 * */ _tcCof : { 'runTime': 50, //每次队列运行时间 'waitTime': 25, //暂停时间 'onRunEnd': QZFL.emptyFn,//队列全部运行完毕触发的事件(只触发一次) 'onWait': QZFL.emptyFn//每次暂停时触发的事件(触发多次,有可能为零次) }, /** * */ _exec : function(value,key,source){ if (!value || _o.getType(value) != "function"){ if (_o.getType(key) == "number") { source[key] = null; } return false; } try { return value(); }catch(e){ QZFL.console.print("QZFL Queue Got An Error: [" + e.name + "] " + e.message,1) } } }; _o.extend(_Queue.prototype,_extend); _o.extend(_Queue,_extend); return _Queue; })(); ///////////// //string.js ///////////// /** * @fileoverview QZFL String 组件 * @version 1.$Rev: 1392 $ * @author QzoneWebGroup, ($LastChangedBy: zishunchen $) */ /** * @namespace QZFL String 封装接口。 * @type */ QZFL.string = { RegExps: { trim: /^\s+|\s+$/g, ltrim: /^\s+/, rtrim: /\s+$/, nl2br: /\n/g, s2nb: /[\x20]{2}/g, URIencode: /[\x09\x0A\x0D\x20\x21-\x29\x2B\x2C\x2F\x3A-\x3F\x5B-\x5E\x60\x7B-\x7E]/g, escHTML: { re_amp: /&/g, re_lt : //g, re_apos : /\x27/g, re_quot : /\x22/g }, escString: { bsls: /\\/g, sls: /\//g, nl: /\n/g, rt: /\r/g, tab: /\t/g }, restXHTML: { re_amp: /&/g, re_lt: /</g, re_gt: />/g, re_apos: /&(?:apos|#0?39);/g, re_quot: /"/g }, write: /\{(\d{1,2})(?:\:([xodQqb]))?\}/g, isURL : /^(?:ht|f)tp(?:s)?\:\/\/(?:[\w\-\.]+)\.\w+/i, cut: /[\x00-\xFF]/, getRealLen: { r0: /[^\x00-\xFF]/g, r1: /[\x00-\xFF]/g }, format: /\{([\d\w\.]+)\}/g }, /** * 通用替换 * * @ignore * @param {string} s 需要进行替换的字符串 * @param {String/RegExp} p 要替换的模式的 RegExp 对象 * @param {string} r 一个字符串值。规定了替换文本或生成替换文本的函数。 * @example * QZFL.string.commonReplace(str + "", QZFL.string.RegExps.trim, ''); * @returns {string} 处理结果 */ commonReplace : function(s, p, r) { return s.replace(p, r); }, /** * 通用系列替换 * * @ignore * @param {string} s 需要进行替换的字符串 * @param {Object} l RegExp对象hashMap * @example * QZFL.string.listReplace(str,regHashmap); * @returns {string} 处理结果 */ listReplace : function(s, l) { if (QZFL.lang.isHashMap(l)) { for (var i in l) { s = QZFL.string.commonReplace(s, l[i], i); } return s; } else { return s+''; } }, /** * 字符串前后去空格 * * @param {string} str 目标字符串 * @example * QZFL.string.trim(str); * @returns {string} 处理结果 */ trim: function(str){ return QZFL.string.commonReplace(str + "", QZFL.string.RegExps.trim, ''); }, /** * 字符串前去空格 * * @param {string} str 目标字符串 * @example * QZFL.string.ltrim(str); * @returns {string} 处理结果 */ ltrim: function(str){ return QZFL.string.commonReplace(str + "", QZFL.string.RegExps.ltrim, ''); }, /** * 字符串后去空格 * * @param {string} str 目标字符串 * @example * QZFL.string.rtrim(str); * @returns {string} 处理结果 */ rtrim: function(str){ return QZFL.string.commonReplace(str + "", QZFL.string.RegExps.rtrim, ''); }, /** * 制造html中换行符 * * @param {string} str 目标字符串 * @example * QZFL.string.nl2br(str); * @returns {string} 结果 */ nl2br: function(str){ return QZFL.string.commonReplace(str + "", QZFL.string.RegExps.nl2br, '
'); }, /** * 制造html中空格符,爽替换 * * @param {string} str 目标字符串 * @example * QZFL.string.s2nb(str); * @returns {string} 结果 */ s2nb: function(str){ return QZFL.string.commonReplace(str + "", QZFL.string.RegExps.s2nb, '  '); }, /** * 对非汉字做URIencode * * @param {string} str 目标字符串 * @example * QZFL.string.URIencode(str); * @returns {string} 结果 */ URIencode: function(str){ var cc, ccc; return (str + "").replace(QZFL.string.RegExps.URIencode, function(a){ if (a == "\x20") { return "+"; } else if (a == "\x0D") { return ""; } cc = a.charCodeAt(0); ccc = cc.toString(16); return "%" + ((cc < 16) ? ("0" + ccc) : ccc); }); }, /** * htmlEscape * * @param {string} str 目标串 * @example * QZFL.string.escHTML(str); * @returns {string} 结果 */ escHTML: function(str){ var t = QZFL.string.RegExps.escHTML; return QZFL.string.listReplace((str + ""), { /* * '&' must be * escape first */ '&' : t.re_amp, '<' : t.re_lt, '>' : t.re_gt, ''' : t.re_apos, '"' : t.re_quot }); }, /** * CstringEscape * * @param {string} str 目标串 * @returns {string} 结果 */ escString: function(str){ var t = QZFL.string.RegExps.escString, h = QZFL.string.RegExps.escHTML; return QZFL.string.listReplace((str + ""), { /* * '\' must be * escape first */ '\\\\' : t.bsls, '\\n' : t.nl, '' : t.rt, '\\t' : t.tab, '\\/' : t.sls, '\\\'' : h.re_apos, '\\"' : h.re_quot }); }, /** * htmlEscape还原 * * @param {string} str 目标串 * @returns {string} 结果 * restHTML: function(str){ if (!QZFL.string.restHTML.__utilDiv) { /** * 工具DIV * * @ignore * QZFL.string.restHTML.__utilDiv = document.createElement("div"); } var t = QZFL.string.restHTML.__utilDiv; t.innerHTML = (str + ""); if (typeof(t.innerText) != 'undefined') { return t.innerText; } else if (typeof(t.textContent) != 'undefined') { return t.textContent; } else if (typeof(t.text) != 'undefined') { return t.text; } else { return ''; } },*/ /** * xhtmlEscape还原 * * @param {string} str 目标串 * @returns {string} 结果 */ restXHTML: function(str){ var t = QZFL.string.RegExps.restXHTML; return QZFL.string.listReplace((str + ""), { /* * '&' must be * escape last */ '<': t.re_lt, '>': t.re_gt, '\x27': t.re_apos, '\x22': t.re_quot, '&': t.re_amp }); }, /** * 字符串格式输出工具 * * @param {string} 输出模式 * @param {Arguments} Arguments... 可变参数,表示模式中占位符处实际要替换的值 * @returns {string} 结果字符串 */ write: function(strFormat, someArgs){ if (arguments.length < 1 || !QZFL.lang.isString(strFormat)) { // rt.warn('No patern to write()'); return ''; } var rArr = QZFL.lang.arg2arr(arguments), result = rArr.shift(), tmp; return result.replace(QZFL.string.RegExps.write, function(a, b, c){ b = parseInt(b, 10); if (b < 0 || (typeof rArr[b] == 'undefined')) { // rt.warn('write() wrong patern:{0:Q}', strFormat); return '(n/a)'; } else { if (!c) { return rArr[b]; } else { switch (c) { case 'x': return '0x' + rArr[b].toString(16); case 'o': return 'o' + rArr[b].toString(8); case 'd': return rArr[b].toString(10); case 'Q': return '\x22' + rArr[b].toString(16) + '\x22'; case 'q': return '`' + rArr[b].toString(16) + '\x27'; case 'b': return '<' + !!rArr[b] + '>'; } } } }); }, /** * 是否是一个可接受的URL串 * * @param {string} s 目标串 * @returns {Boolean} 结果 */ isURL: function(s){ return QZFL.string.RegExps.isURL.test(s); }, /** * 包装的escape函数 Deprecated * * @param {string} s 源字符串 * @returns {string} 结果串 * @deprecated 最早期为了支持很差浏览器的用法,现在不需要了 */ escapeURI: function(s){ if (window.encodeURIComponent) { return encodeURIComponent(s); } if (window.escape) { return escape(s); } return ''; }, /** * 用指定字符补足需要的数字位数 * * @param {string} s 源字符串 * @param {number} l 长度 * @param {string} [ss="0"] 指定字符 * @param {boolean} [isBack=false] 补足的方向: true 后方; false 前方; * @returns {string} 返回的结果串 */ fillLength: function(source, l, ch, isRight){ if ((source = String(source)).length < l) { var ar = new Array(l - source.length); ar[isRight ? 'unshift' : 'push'](source); source = ar.join(ch || '0'); } return source; }, /** * 用制定长度切割给定字符串 * * @param {string} s 源字符串 * @param {number} bl 期望长度(字节长度) * @param {string} tails 增加在最后的修饰串,比如"..." * @returns {string} 结果串 */ cut: function(str, bitLen, tails){ str = String(str); bitLen -= 0; tails = tails || ''; if (isNaN(bitLen)) { return str; } var len = str.length, i = Math.min(Math.floor(bitLen / 2), len), cnt = QZFL.string.getRealLen(str.slice(0, i)); for (; i < len && cnt < bitLen; i++) { cnt += 1 + (str.charCodeAt(i) > 255); } return str.slice(0, cnt > bitLen ? i - 1 : i) + (i < len ? tails : ''); }, /** * 计算字符串的真实长度 * * @param {string} s 源字符串 * @param {boolean} [isUTF8=false] 标示是否是utf-8计算 * @returns {number} 结果长度 */ getRealLen: function(s, isUTF8){ if (typeof(s) != 'string') { return 0; } if (!isUTF8) { return s.replace(QZFL.string.RegExps.getRealLen.r0, "**").length; } else { var cc = s.replace(QZFL.string.RegExps.getRealLen.r1, ""); return (s.length - cc.length) + (encodeURI(cc).length / 3); } }, format: function(str){ var args = Array.prototype.slice.call(arguments), v; str = String(args.shift()); if (args.length == 1 && typeof(args[0]) == 'object') { args = args[0]; } QZFL.string.RegExps.format.lastIndex = 0; return str.replace(QZFL.string.RegExps.format, function(m, n){ v = QZFL.object.route(args, n); return v === undefined ? m : v; }); } }; /** * htmlEscape还原 * * @deprecated 不要再用了,这里对接的新的实现上 * @param {string} str 目标串 * @returns {string} 结果 */ QZFL.string.restHTML = QZFL.string.restXHTML; ///////////// //util.js ///////////// /** * @fileoverview QZFL 通用接口核心库 * @version 1.$Rev: 1392 $ * @author QzoneWebGroup, ($LastChangedBy: zishunchen $) * @lastUpdate $Date: 2009-08-05 16:26:13 +0800 (Wed, 05 Aug 2009) $ */ /** * 小工具方法包,一些分类不确定的公共方法 * @namespace 小工具方法包 */ QZFL.util = { /** * 使用一个uri串制作一个类似location的对象 * * @param {string} s 所需字符串 * @returns {object} QZFL.util.URI的实例 * @see QZFL.util.URI */ buildUri : function(s) { return new QZFL.util.URI(s); }, /** * 使用一个uri串制作一个类似location的对象 * * @class URI引擎,可以把一个uri字符串转换成类似location的对象 * @constructor * @param {string} s 所需字符串 */ URI : function(s) { if (!(QZFL.object.getType(s) == "string")) { return null; } if(s.indexOf('//')==0){ //双斜杠开头的,直接自适应协议 s = window.location.protocol + s; } if (s.indexOf("://") < 1) { s = location.protocol + "//" + location.host + (s.indexOf("/") == 0 ? "" : location.pathname.substr(0, location.pathname.lastIndexOf("/") + 1)) + s; } var depart = s.split("://"); if (QZFL.object.getType(depart) == "array" && depart.length > 1 && (/^[a-zA-Z]+$/).test(depart[0])) { /** * 协议类型 * @field * @type string */ this.protocol = depart[0].toLowerCase(); var h = depart[1].split("/"); if (QZFL.object.getType(h) == "array") { /** * 主机描述 * @field * @type string */ this.host = h[0]; /** * 资源路径 * @field * @type string */ this.pathname = "/" + h.slice(1).join("/").replace(/(\?|\#).+/i, ""); // 修正pathname的返回错误 /** * 请求URL全描述 * @field * @type string */ this.href = s; var se = depart[1].lastIndexOf("?"), ha = depart[1].lastIndexOf("#"); /** * query string * @field * @type string */ this.search = (se >= 0) ? depart[1].substring(se) : ""; /** * page fragment anchor * @field * @type string */ this.hash = (ha >= 0) ? depart[1].substring(ha) : ""; if (this.search.length > 0 && this.hash.length > 0) { if (ha < se) { this.search = ""; } else { this.search = depart[1].substring(se, ha); } } return this; } else { return null; } } else { return null; } } }; ///////////// //lang.js ///////////// /** * @fileoverview 增强脚本语言处理能力 * @version 1.$Rev: 1597 $ * @author QzoneWebGroup, ($LastChangedBy: ryanzhao $) * @lastUpdate $Date: 2009-11-30 21:51:19 +0800 (星期一, 30 十一月 2009) $ */ /** * 环境变量系统 * * @namespace QZFL.lang */ QZFL.lang = { /** * 是否字符串 * * @param {object} o 目标 * @returns {boolean} 结果 * @example QZFL.lang.isString(obj); */ isString : function(o) { return QZFL.object.getType(o) == "string"; }, /** * 是否数组对象 * * @param {object} o 目标 * @returns {boolean} 结果 * @example QZFL.lang.isArray(obj); */ isArray : function(o) { return QZFL.object.getType(o) == "array"; }, /** * 是否函数对象 * * @param {object} o 目标 * @returns {boolean} 结果 * @example QZFL.lang.isArray(obj); */ isFunction: function(o) { return QZFL.object.getType(o) == "function"; }, /** * 是否哈希表结构 * * @param {object} o 目标 * @returns {boolean} 结果 * @example QZFL.lang.isHashMap(obj); */ isHashMap : function(o) { return QZFL.object.getType(o) == "object"; }, /** * 是否Node节点对象 * * @param {object} o 目标 * @returns {boolean} 结果 * @example QZFL.lang.isNode(obj); */ isNode : function(o) { return o && (typeof(o.nodeName) != 'undefined' || typeof(o.nodeType) != 'undefined'); }, /** * 是否Element * * @param {object} o 目标 * @returns {boolean} 结果 * @example QZFL.lang.isElement(obj); */ isElement : function(o) { return o && o.nodeType == 1; } }; ///////////// //util_ex.js ///////////// /** * @fileoverview QZFL.util 小工具扩展包 * @version 1.$Rev: 1921 $ * @author QzoneWebGroup ($LastChangedBy: ryanzhao $) - $Date: 2011-01-11 18:46:01 +0800 (周二, 11 一月 2011) $ */ (function() { var evalGlobalCnt = 0, runStyleGlobalCnt = 0; /** * QZFL.util 工具包扩展 * @namespace QZFL.util 命名空间 * @name QZFL.util * */ QZFL.object.extend(QZFL.util, /** @lends QZFL.util */{ /** * 复制到剪贴板,目前只支持IE 已经将上个版本jolt增加的剪贴板控制去除 * @param {string} text 要复制的文本 * @returns {boolean} 写入剪贴板是否成功 * @deprecated 认为在这里逻辑过多,建议设计统一的widget组件交付各个应用使用 * @example QZFL.util.copyToClip(text); */ copyToClip : function(text) { if (QZFL.userAgent.ie) { return clipboardData.setData("Text", text); } else { var o = QZFL.shareObject.getValidSO(); return o ? o.setClipboard(text) : false; } }, /** * 在页面上执行一段js语句文本 * 这个是直接在全局部分执行,在js系统的任意部分调用也能保证在全局执行一段脚本 * @param {string} js 一段js语句文本 * @example QZFL.util.evalGlobal("var t = 1;"); */ evalGlobal : function(js) { js = String(js); var obj = document.createElement('script'), head = document.documentElement || document.getElementsByTagName("head")[0]; obj.type = 'text/javascript'; obj.id = "__evalGlobal_" + evalGlobalCnt; try { obj.innerHTML = js; } catch (e) { obj.text = js; } head.insertBefore(obj,head.firstChild); evalGlobalCnt++; setTimeout(function(){QZFL.dom.removeElement(obj);}, 50); }, /** * 在页面上执行一段css语句文本 * @deprecated 专供safari使用 * @param {string} st 一段style语句 * @example QZFL.util.runStyleGlobal("body { font-size: 12px; }"); */ runStyleGlobal : function(st) { if (QZFL.userAgent.safari) { var obj = document.createElement('style'); obj.type = 'text/css'; obj.id = "__runStyle_" + runStyleGlobalCnt; try { obj.textContent = st; } catch (e) { alert(e.message); } var h = document.getElementsByTagName("head")[0]; if (h) { h.appendChild(obj); runStyleGlobalCnt++; } } else { // rt.warn("plz use runStyleGlobal() in Safari!"); } }, /** * http参数表对象变为HTTP协议数据串,如:param1=123&param2=456 * @param {object} o 用来表示参数列表的hashTable * @returns {string} 结果串 * @example QZFL.util.genHttpParamString({"param1":123, "param2":456}); */ genHttpParamString : function(o) { return QZFL.util.commonDictionaryJoin(o, null, null, null, window.encodeURIComponent); }, /** * 将一个http参数序列字符串变为表映射对象 * @param {string} s 源字符串 * @returns {object} 结果 * @example QZFL.util.splitHttpParamString("param1=123¶m2=456"); */ splitHttpParamString : function(s) { return QZFL.util.commonDictionarySplit(s); }, /** * 将一个字典型序列字符串变为映射表对象 * @param {string} [s=''] 源字符串 * @param {string} [esp='&'] 项分隔符 * @param {string} [vq=''] 值封套 * @param {string} [eq='='] 等号字符 * @returns {object} 结果对象 * @example QZFL.util.commonDictionarySplit( 'form-data; name="file_upload"; file_name="c:\\data\\data.ini"; ', '; ', '"', '=' ); */ commonDictionarySplit : function(s, esp, vq, eq) { var res = {}, l, ks, vs, t; if(!s || typeof(s) != "string"){ return res; } if (typeof(esp) != 'string') { esp = "&"; } if (typeof(vq) != 'string') { vq = ""; } if (typeof(eq) != 'string') { eq = "="; } l = s.split(esp); //a="1=2"tt"&b="2"s=t" -> a="1=2"tt" b="2"s=t" if(l && l.length){ for(var i = 0, len = l.length; i < len; ++i){ ks = l[i].split(eq); //a="1=2"tt" -> a "1 2"tt" if(ks.length > 1){ t = ks.slice(1).join(eq); //"1=2"tt" vs = t.split(vq); res[ks[0]] = vs.slice(vq.length, vs.length - vq.length).join(vq); }else{ ks[0] && (res[ks[0]] = true); //没有值的时候直接就用true作为值 } } } return res; }, /** * 将一个字典型映射表对象变为序列字符串 * @param {object} [o={}] 源映射对象 * @param {string} [esp='&'] 项分隔符 * @param {string} [vq=''] 值封套 * @param {string} [eq='='] 等号字符 * @param {function} [valueHandler=QZFL.emptyFn] 处理值的方法引用 * @returns {string} 结果串 * @example QZFL.util.commonDictionaryJoin( { 'form-data' : true, 'name' : 'file_upload', 'file_name' : 'c:\\data\\data.ini' } '; ', '"', '=' ); //form-data="true"; name="file_upload"; file_name="c:\\data\\data.ini" */ commonDictionaryJoin : function(o, esp, vq, eq, valueHandler) { var res = [], t; if(!o || typeof(o) != "object"){ return ''; } if(typeof(o) == "string"){ return o; } if (typeof(esp) != 'string') { esp = "&"; } if (typeof(vq) != 'string') { vq = ""; } if (typeof(eq) != 'string') { eq = "="; } for(var k in o){ res.push(k + eq + vq + (typeof valueHandler == 'function' ? valueHandler(o[k]) : o[k]) + vq); } return res.join(esp); } }); })(); ///////////// //lang_ex.js ///////////// /** * @fileoverview 增强脚本语言处理能力 * @version 1.$Rev: 1921 $ * @author QzoneWebGroup, ($LastChangedBy: ryanzhao $) * @lastUpdate $Date: 2011-01-11 18:46:01 +0800 (周二, 11 一月 2011) $ */ /** * 是否是有效的xml数据对象 * * @param {object} o xmldom对象 * @returns {boolean} 结果 * @example QZFL.lang.isValidXMLdom(obj); */ QZFL.lang.isValidXMLdom = function(o) { return !!(o && o.xml && /^<\?xml/.test(o.xml)); //ryan }; /** * 将arguments对象转化为真数组 * * @param {object} refArgs 对一个arguments对象的引用 * @param {number} [start=0] 起始偏移量 * @returns {object} 结果数组 * @example QZFL.lang.arg2arr(obj, 1); //从第二个参数开始转化 */ QZFL.lang.arg2arr = function(refArgs, start) { return Array.prototype.slice.call(refArgs, (start || 0)); }; /** * 以window为根,获取指定命名描述的值 * * @param {string} ns 描述, 如: QZFL.foo.bar * @param {boolean} [setup=false] 不存在则创建 * @example QZFL.lang.getObjByNameSpace("QZFL.foo.bar", true); * @returns {string|number|function|object|undefined} 获取到得值 */ QZFL.lang.getObjByNameSpace = function(ns, setup) { if (typeof(ns) != 'string') { return ns; } var l = ns.split("."), r = window; try { for (var i = 0, len = l.length; i < len; ++i) { if(typeof(r[l[i]]) == 'undefined'){ if(setup){ r[l[i]] = {}; }else{ return; } } r = r[l[i]]; } return r; } catch (ignore) { return; } }; /** * JSON数据深度复制 * * @param {string|number|function|object|undefined} obj 需要复制的JSON数据根部 * @param {String} preventName 需要过滤的字段 * @returns {string|number|function|object|undefined} 复制出的新JSON数据 * @example QZFL.lang.objectClone(re, "msg"); */ QZFL.lang.objectClone = function(obj, preventName) { if ((typeof obj) == 'object') { var res = (QZFL.lang.isArray(obj)) ? [] : {}; for (var i in obj) { if (i != preventName) res[i] = QZFL.lang.objectClone(obj[i], preventName); } return res; } else if ((typeof obj) == 'function') { return Object; } return obj; }; /** * JS Object convert to String * @param {string|number|function|object|undefined} obj * @returns {string} result * @example QZFL.lang.obj2str(obj); */ QZFL.lang.obj2str = function(obj) { var t, sw; if (typeof(obj) == 'object') { if(obj === null){ return 'null'; } if(window.JSON && window.JSON.stringify){ return JSON.stringify(obj); } sw = QZFL.lang.isArray(obj); t = []; for (var i in obj) { t.push((sw ? "" : ("\"" + QZFL.string.escString(i) + "\":")) + obj2str(obj[i])); } t = t.join(); return sw ? ("["+t+"]") : ("{"+t+"}"); } else if (typeof(obj) == 'undefined') { return 'undefined'; } else if (typeof(obj) == 'number' || typeof(obj) == 'function') { return obj.toString(); } return !obj ? "\"\"" : ("\"" + QZFL.string.escString(obj) + "\""); }; /** * 对象成员复制(浅表复制) * * @param {object} s 复制的目标对象 * @param {object} b 复制的源对象 * @param {object} [propertiSet] 所需要的属性名称集合 * @param {boolean} [notOverWrite=false] 不复写 * @returns {object} 目标对象 * @example QZFL.lang.propertieCopy(objt, objs, parray, false); */ QZFL.lang.propertieCopy = function(s, b, propertiSet, notOverWrite) { // 如果propertiSet == null 或者 != Object,则使用b。 var l = (!propertiSet || typeof(propertiSet) != 'object') ? b : propertiSet; s = s || {}; for (var p in l) { if (!notOverWrite || !(p in s)) { s[p] = l[p]; } } return s; }; /** * 顺序执行一系列方法,得到第一个成功执行的结果 * * @param {function} arguments... 可变参数,一系列函数执行 * @returns {string|number|function|object|undefined} 执行结果 * @example QZFL.lang.tryThese(functionOne, functionTwo, functionThree); */ QZFL.lang.tryThese = function(){ for (var i = 0, len = arguments.length; i < len; ++i) { try { return arguments[i](); } catch (ign) {} } return; }; /** * 将两个执行过程连接起来,注意,连接后不可再分开,且执行过程用Boolean型数据标识是否成功执行 * * @param {function} u 要先执行的过程 * @param {function} v 后执行的过程 * @returns {function} 连接后的执行过程 * @example QZFL.lang.chain(functionOne, functionTwo); */ QZFL.lang.chain = function(u, v) { var calls = QZFL.lang.arg2arr(arguments); return function() { for (var i = 0, len = calls.length; i < len; ++i) { if (calls[i] && calls[i].apply(null, arguments) === false) { return false; } } return true; }; }; /** * 去除数组中重复的元素 * * @param {object} arr 源数组 * @returns {object} 去除重复元素后的数组 * @example QZFL.lang.uniqueArray(arr); */ QZFL.lang.uniqueArray = function(arr) { if(!QZFL.lang.isArray(arr)){ return arr; } var flag = {},index = 0; while (index < arr.length) { if (flag[arr[index]] == typeof(arr[index])) { arr.splice(index, 1); continue; } flag[arr[index].toString()] = typeof(arr[index]); ++index; } return arr; }; ///////////// //env.js ///////////// /** * @fileoverview 封闭静态类ENV,管理环境变量 * @version 1.$Rev: 1921 $ * @author QzoneWebGroup, ($LastChangedBy: ryanzhao $) * @lastUpdate $Date: 2011-01-11 18:46:01 +0800 (周二, 11 一月 2011) $ */ /** * 环境变量系统 * * @namespace QZFL.enviroment */ QZFL.enviroment = (function() { var _p = {}, hookPool = {}; /** * 获取指定的环境变量 * * @ignore * @param {String} kname 指定的环境变量名称 * @return {All} 存储在环境变量中的数据 * @example * QZFL.enviroment.envGet(kname); */ function envGet(kname) { return _p[kname]; } /** * 删除指定的环境变量 * * @ignore * @param {String} kname 指定的环境变量名称 * @return {Boolean} 是否删除成功 * @example * QZFL.enviroment.envDel(kname); */ function envDel(kname) { delete _p[kname]; return true; } /** * 以指定名称设置环境变量 * * @ignore * @param {String} kname 名称 * @param {All} value 值 * @return {Boolean} 是否成功 * @example * QZFL.enviroment.envSet(kname,value); */ function envSet(kname, value) { if (typeof value == 'undefined') { if (typeof kname == 'undefined') { return false; } else if (!(_p[kname] === undefined)) { return false; } } else { _p[kname] = value; return true; } } return { /** * 获取指定的环境变量 * * @param {String} kname 指定的环境变量名称 * @return {All} 存储在环境变量中的数据 * @memberOf QZFL.enviroment */ get : envGet, /** * 以指定名称设置环境变量 * * @param {String} kname 名称 * @param {All} value 值 * @return {Boolean} 是否成功 * @memberOf QZFL.enviroment */ set : envSet, /** * 删除指定的环境变量 * * @param {String} kname 指定的环境变量名称 * @return {Boolean} 是否删除成功 * @memberOf QZFL.enviroment */ del : envDel, /** * 事件钩子存放根 * * @type {Object} * @memberOf QZFL.enviroment */ hookPool : hookPool }; })(); /** * 页面级别事件处理 * * @namespace QZFL.pageEvents * @example * QZFL.pageEvents.pageBaseInit(); * QZFL.pageEvents.onloadRegister(init); */ QZFL.pageEvents = (function() { /** * 将queryString解析到环境变量 * * @ignore */ function _ihp() { var qs = location.search.substring(1), qh = location.hash.substring(1), s, h, n; ENV.set("_queryString", qs); ENV.set("_queryHash", qh); ENV.set("queryString", s = QZFL.util.splitHttpParamString(qs)); ENV.set("queryHash", h = QZFL.util.splitHttpParamString(qh)); //为QZFL设置调试级别 if(s && s.DEBUG){ n = parseInt(s.DEBUG, 10); if (!isNaN(n)) { QZFL.config.debugLevel = n; } } } /** * 页面启动器 * * @ignore */ function _bootStrap() { if(QZFL.event.onDomReady.isReady){ setTimeout(_onloadHook,1); }else if (document.addEventListener) { document.addEventListener("DOMContentLoaded", _onloadHook, true); } else { var src = (window.location.protocol == 'https:') ? '//:' : 'javascript:void(0)'; document.write(' * @example * var fs = new QZFL.FormSender(APPLY_ENTRY_RIGHT,"post",{"hUin": getParameter("uin"),"vUin":checkLogin(),"msg":$("msg-area").value, "rd": Math.random()}, "utf-8"); * fs.onSuccess = function(re) {}; * fs.onError = function() {}; * fs.send(); * */ QZFL.FormSender = function(actionURL, method, data, charset) { /** * form的名称,默认为 _fpInstence_ + 计数 * * @type string */ this.name = "_fpInstence_" + QZFL.FormSender.counter; QZFL.FormSender.instance[this.name] = this; QZFL.FormSender.counter++; var c = String(charset).toLowerCase(); if(typeof(actionURL) == 'object' && actionURL.nodeType == 1 && actionURL.tagName == 'FORM'){ this.instanceForm = actionURL; }else{ //standard mode /** * 数据发送方式 * * @type string */ this.method = method || "POST"; /** * 数据请求地址 * * @type string */ this.uri = actionURL; /** * 数据请求的编码格式 * * @type string */ this.charset = (c == 'utf-8' || c == 'gbk' || c == 'gb2312' || c == 'gb18030') ? c : 'gb2312'; /** * 数据参数表 * * @type object */ this.data = (typeof(data) == "object" || typeof(data) == 'string') ? data : null; this.proxyURL = (this.charset == "utf-8") ? QZFL.config.FSHelperPage.replace(/_gbk/, "_utf8") : QZFL.config.FSHelperPage; } this._sender = null; /** * 服务器正确响应时的处理 * * @event */ this.onSuccess = QZFL.emptyFn; /** * 服务器无响应或预定的不正常响应处理 * * @event */ this.onError = QZFL.emptyFn; // 宿主对象 this.ownerWindow = window; // 准备时间 this.startTime = 0; // 成功回调时间 this.endTime = 0; // 发送请求时间 this.postTime = 0; }; QZFL.FormSender.instance = {}; QZFL.FormSender.counter = 0; QZFL.FormSender._errCodeMap = { 999 : { msg : 'Connection or Server error' } }; QZFL.FormSender.pluginsPool = { "formHandler" : [] , "onErrorHandler" : [] }; QZFL.FormSender._pluginsRunner = function(pType, data){ var _s = QZFL.FormSender , l = _s.pluginsPool[pType] , t = data , len ; if(l && (len = l.length)){ for(var i = 0; i < len; ++i){ if(typeof(l[i]) == "function"){ t = l[i](t) || data; } } } return t; }; QZFL.FormSender._clear = function(o){ o._sender = o._sender.callback = o._sender.errorCallback = null ; if (QZFL.userAgent.safari || QZFL.userAgent.opera) { setTimeout('QZFL.dom.removeElement(document.getElementById("_fp_frm_' + o.name + '"))', 50); } else { QZFL.dom.removeElement(document.getElementById("_fp_frm_" + o.name)); } // 完成了一次请求 o.endTime = +new Date; QZFL.FormSender._pluginsRunner('onRequestComplete', o); o.instanceForm = null; }; /** * 发送请求 * * @return {Boolean} 是否成功 */ QZFL.FormSender.prototype.send = (function() { var win = window; (function (callback) { var _cur = window, flag, cnt = 0, _pool = []; while (true) { flag = false; try { _cur.document && _cur.document.domain == document.domain && (flag = true); } catch (_) { } if (flag) { _pool.push(_cur); } if (_cur == top) { break; } _cur = _cur.parent; } while (_pool.length) { if (callback(_cur = _pool.pop()) === true) { return _cur; } } return null; })(function (w) { if (w.QZFL && w.QZFL.FormSender && w.QZFL.cookie) { win = w; return true; } }); var host = win.location.host, cookieflag = win.QZFL.cookie.get('blabla') == 'dynamic', extend = QZFL.object.extend; return function() { // 记录一个开始时间点 this.startTime = +new Date; var isspeedup = cookieflag && (/(?:^user\.(s\d\.)?|\d{5,}\.|rc\.)qzone\.qq\.com/.test(host)), realurl = this.uri , ajaxurl = realurl, path, tmplURI, canUseXHR = win.QZFL.config.canUseXHR2Browser(); // iframe请求代理到父页面 // 加一个xhrProxyEnable的配置 以防失败时直接切回原来的模式 // 利用白名单 对目标url符合白名单才进行xhr请求代理 // 只针对utf-8编码才进行 if (this.charset == 'utf-8') { if (canUseXHR && win.QZFL && win.QZFL.FormSender // #1.可以使用代理并且允许使用 // #2.可以使用xhr2 ) { var data = typeof this.data == 'object' ? extend(this.data, {qzreferrer: location.href}) : [this.data, 'qzreferrer=' + encodeURIComponent(location.href)].join('&'); var targetUrl = transUrl2HttpsIfNeed(realurl); targetUrl = targetUrl+ ( targetUrl.indexOf('?')>-1 ? '&' : '?')+ (QZFL.win.g_qzonetoken ? 'qzonetoken='+QZFL.win.g_qzonetoken : ''); tmplURI = QZFL.util.URI(targetUrl); this.speedup = 1; var th = this; return (this.type = 'xhr'), win.QZFL.ajaxPost( targetUrl, data, { onload: function(rsp){ // debugger; try{ //跨域的话会取不到这个头而报错,所以try一下 th._sslinfo = this.getResponseHeader('x-stgw-ssl-info') || ''; }catch(err){} th.endTime = +new Date; th.onSuccess(rsp); }, instance: this, headers: isspeedup ? { 'X-Real-Url': realurl } : {} }), (this.postTime = +new Date); } } if (this._sender === null || this._sender === void(0)) { var timer , sender = document.createElement("iframe") ; sender.id = sender.name = "_fp_frm_" + this.name; sender.style.cssText = "width:0;height:0;border-width:0;display:none;"; sender.callback = (function(th) { return function(){ th.resultArgs = arguments; th.msg = 'ok'; th.onSuccess.apply(th, arguments); win.QZFL.FormSender._clear(th); //逻辑失败上报 if (arguments && arguments[0].code !== 0) { var _time = 0; if(th.endTime != undefined && th.startTime != undefined) { _time = th.endTime - th.startTime; } errcodeReport({ code: arguments[0].code, cgi: th.uri, pathname: location.pathname, time: _time }); returnCodeReport({ appid: '20141', url: th.uri, type: 2, code: arguments[0].code }); } else { returnCodeReport({ appid: '20141', url: th.uri, type: 1, code: arguments[0].code }); } } }) (this); var errcallback = (function (th) { var f = function () { th.resultArgs = arguments; th.msg = QZFL.FormSender._errCodeMap[999].msg; win.QZFL.FormSender._pluginsRunner('onErrorHandler', th); win.QZFL.FormSender._clear(th); th.onError(); }; return function () { // th.resultArgs存在则已触发成功回调了 // ie下如果src没设上则证明是初始化的 // 非ie如果进入这里则已经证明其出错了 if (typeof th.resultArgs == 'object') { return; } if (this.readyState == 'complete' || typeof this.readyState == 'undefined') { if ('sended'.indexOf(this.state) > -1) { this.onload = this.onreadystatechange = null; f(); } } var _time = 0; if(th.endTime != undefined && th.startTime != undefined) { _time = th.endTime - th.startTime; } //http失败上报 errcodeReport({ code: 502, cgi: th.uri, pathname: location.pathname, time: _time }); returnCodeReport({ appid: '20141', url: th.uri, type: 3, code: 502 }); } }) (this); document.body.appendChild(sender); sender.errorCallback = errcallback; sender.onload = sender.onreadystatechange = errcallback; sender.state = 'initing'; this._sender = sender; } if(!this.instanceForm){ var t = this, ie = QZFL.userAgent.ie,ff =QZFL.userAgent.firefox, ifrurl, ifrHTML,data = t.data; var targetURL = t.uri; // 因为跨域问题,formsender不能从http targetURL = transUrl2HttpsIfNeed(targetURL, true); //先加上g_tk和qzonetoken targetURL = targetURL + (targetURL.indexOf('?') > -1 ? '&' : '?') + 'g_tk=' + QZFL.pluginsDefine.getACSRFToken(targetURL) +(QZFL.win.g_qzonetoken ? '&qzonetoken='+QZFL.win.g_qzonetoken : ''); ifrHTML = ''; if (ie || ff) { ifrurl = 'javascript:document.open();document.domain="' + document.domain + '";var me=parent.QZFL.FormSender.instance["' + t.name + '"];document.write(me.ifrHTML);document.close();'; } ifrHTML = ifrHTML + '