Query是目前在JavaScript领域上最广泛流行的框架,无奈这次把他加到 ECShop的时候就遇到一个十分头疼的问题。 ECShop把AJAX事件和JSON解析的模块放在common/transport.js之中,可以说它也有自己封装的一套工具,这其实是很正常的。 但恰恰的,在封装JSON各种方法的同时对object的模型进行了重写,这个就跟jQuery冲突了。因为众所周知的,jQuery对各种 JavaScript对象进行了扩展。 我在开发康比特网站的时候也遇到了这个问题,需要用放大镜效果、仿淘宝的物流追踪等功能时,都会发生冲突。在ECShop论坛上原来也有很多朋友提出了这个问题,也提出了各种各样的方法,我尝试了一些,不好或者甚至无用,所以只好自己动手了。 解决思路: 一切起因就是在于两者都重写了Object,所以当然任意一方让步就可以了。在这里我选择了修改代码量比较少的transport.js,除了简单,更重要的是去修改jQuery的话框架提供的强大特效和各种敏捷方法就失效了,还不是得不偿失。 1、加入JSON2.js文件 原因很简单,transport修改Object是为了加入支持JSON的方法。所以我这里用JSON官网在javascript语言上提供的json2.js支持具体下载地址 http://www./json2.js,从官方下载下来的json2.js 第一句话需要注释:alert(‘IMPORTANT: Remove this line from json2.js beforedeployment.’); 否则的话 加载json2.js页面 就会弹出 2、修改transport.js 2.1 注释掉重写object的方法,具体搜索 Js代码 1. if ( ! Object.prototype.toJSONString) { if ( ! Object.prototype.toJSONString) { 这一段代码,然后把里面的内容全部注释掉。(参考:注释掉496-737行) 2.2 加入新的JSON支持方法 Js代码 1. function objToJSONString(obj, filter){ 2. return JSON.stringify(obj, filter); 3. } 4. 5. function parseObjectToJSON(object, filter){ 6. return JSON.parse(object, filter); 7. } function objToJSONString(obj, filter){ return JSON.stringify(obj, filter); } function parseObjectToJSON(object, filter){ return JSON.parse(object, filter); } 也可以看到其实都很简单,都是调用json2.js里面提供的方法,有人觉得不必在这里添加直接调用也可以,但我还是建议做这样的一个适配器在这,因为容易容易表明用意。 2.3 修正AJAX方法 2.3.1 在transport.js搜索params.toJSONString() 改为 objToJSONString(params) 2.3.2 继续在transport.js搜索result.parseJSON() 改为 parseObjectToJSON(result)(具体在408行左右) 3、修复旧JSON调用地方 简单来说就是把所有*.toJSONString() 的调用改为用objToJSONString(*),而*.parseJSON()改为parseObjectToJSON(*)。 例如: comm.js里面第一个函数里面的 Ajax.call(‘flow.php?step=add_to_cart’, ‘goods=’ + goods.toJSONString(), addToCartResponse, ‘POST’, ‘JSON’); 要改为Ajax.call(‘flow.php?step=add_to_cart’, ‘goods=’ + objToJSONString(goods), addToCartResponse, ‘POST’, ‘JSON’); comm.js里面还有一些Ajax.call调用tojsonstring的,都需要按照本例替换。 我个人建议全部替换,如果当时不替换 如果再次二次开发时 又发生冲突 还得查资料 还不如一下搞定 ,js文件也不多 我自己修改时用了10多分钟就搞定了,建议在header里面就加入了json2.js 最好的解决方案就坐等ECShop来搞定了。 同样的,这次的冲突不具备特殊性,也是一次很好的经验,因为以后遇到修改object等对象的场合并不会少,有这次的经验就知道如何应对了。 PS:附件为修复后的transport.js文件,注意调用之前必须加入json2.js文件。 附加:transport.js修改版代码 var Transport = { filename : “transport.js”, debugging : { isDebugging : 0, debuggingMode : 0, linefeed : “”, containerId : 0 }, debug : function (isDebugging, debuggingMode) { this.debugging = { “isDebugging” : isDebugging, “debuggingMode” : debuggingMode, “linefeed” : debuggingMode ? “<br />” : “\n”, “containerId” : “dubugging-container” + new Date().getTime() }; }, onComplete : function () { }, onRunning : function () { }, run : function (url, params, callback, transferMode, responseType, asyn, quiet) { params = this.parseParams(params); transferMode = typeof(transferMode) === “string” && transferMode.toUpperCase() === “GET” “GET” : “POST”; if (transferMode === “GET”) { var d = new Date(); url += params ? (url.indexOf(“?”) === – 1 ? “?” : “&”) + params : “”; url = encodeURI(url) + (url.indexOf(“?”) === – 1 ? “?” : “&”) + d.getTime() + d.getMilliseconds(); params = null; } responseType = typeof(responseType) === “string” &&((responseType = responseType.toUpperCase()) === “JSON” || responseType=== “XML”) ? responseType : “TEXT”; asyn = asyn === false ? false : true; var xhr = this.createXMLHttpRequest(); try { var self = this; if (typeof(self.onRunning) === “function” && !quiet) { self.onRunning(); } xhr.open(transferMode, url, asyn); if (transferMode === “POST”) { xhr.setRequestHeader(“Content-Type”, “application/x-www-form-urlencoded”); } if (asyn) { xhr.onreadystatechange = function () { if (xhr.readyState == 4) { switch ( xhr.status ) { case 0: case 200: // OK! if (typeof(self.onComplete) === “function”) { self.onComplete(); } if (typeof(callback) === “function”) { callback.call(self, self.parseResult(responseType, xhr), xhr.responseText); } break; case 304: // Not Modified break; case 400: // Bad Request alert(“XmlHttpRequest status: [400] Bad Request”); break; case 404: // Not Found alert(“XmlHttpRequest status: [404] \nThe requested URL “+url+” was not found on this server.”); break; case 409: // Conflict break; case 503: // Service Unavailable alert(“XmlHttpRequest status: [503] Service Unavailable”); break; default: alert(“XmlHttpRequest status: [" + xhr.status + "] Unknow status.”); } xhr = null; } } if (xhr != null) xhr.send(params); } else { if (typeof(self.onRunning) === “function”) { self.onRunning(); } xhr.send(params); var result = self.parseResult(responseType, xhr); //xhr = null; if (typeof(self.onComplete) === “function”) { self.onComplete(); } if (typeof(callback) === “function”) { callback.call(self, result, xhr.responseText); } return result; } } catch (ex) { if (typeof(self.onComplete) === “function”) { self.onComplete(); } alert(this.filename + “/run() error:” + ex.description); } }, displayDebuggingInfo : function (info, type) { if ( ! this.debugging.debuggingMode) { alert(info); } else { var id = this.debugging.containerId; if ( ! document.getElementByIdx_x(id)) { div = document.createElement_x(“DIV”); div.id = id; div.style.position = “absolute”; div.style.width = “98%”; div.style.border = “1px solid #f00″; div.style.backgroundColor = “#eef”; var pageYOffset = document.body.scrollTop || window.pageYOffset || 0; div.style.top = document.body.clientHeight * 0.6 + pageYOffset + “px”; document.body.appendChild(div); div.innerHTML = “<div></div>” + “<hr style=’height:1px;border:1px dashed red;’>” + “<div></div>”; } var subDivs = div.getElementsByTagName_r(“DIV”); if (type === “param”) { subDivs[0].innerHTML = info; } else { subDivs[1].innerHTML = info; } } }, createXMLHttpRequest : function () { var xhr = null; if (window.ActiveXObject) { var versions = ['Microsoft.XMLHTTP', 'MSXML6.XMLHTTP','MSXML5.XMLHTTP', 'MSXML4.XMLHTTP', 'MSXML3.XMLHTTP', 'MSXML2.XMLHTTP','MSXML.XMLHTTP']; for (var i = 0; i < versions.length; i ++ ) { try { xhr = new ActiveXObject(versions[i]); break; } catch (ex) { continue; } } } else { xhr = new XMLHttpRequest(); } return xhr; }, onXMLHttpRequestError : function (xhr, url) { throw “URL: ” + url + “\n” + “readyState: ” + xhr.readyState + “\n” + “state: ” + xhr.status + “\n” + “headers: ” + xhr.getAllResponseHeaders(); }, parseParams : function (params) { var legalParams = “”; params = params ? params : “”; if (typeof(params) === “string”) { legalParams = params; } else if (typeof(params) === “object”) { try { legalParams = “JSON=” + objToJSONString(params); } catch (ex) { alert(“Can’t stringify JSON!”); return false; } } else { alert(“Invalid parameters!”); return false; } if (this.debugging.isDebugging) { var lf = this.debugging.linefeed, info = “[Original Parameters]” + lf + params + lf + lf + “[Parsed Parameters]” + lf + legalParams; this.displayDebuggingInfo(info, “param”); } return legalParams; }, preFilter : function (result) { return result.replace(/\xEF\xBB\xBF/g, “”); }, parseResult : function (responseType, xhr) { var result = null; switch (responseType) { case “JSON” : result = this.preFilter(xhr.responseText); try { result = parseObjectToJSON(result);//EditBy Qiurc 2010年6月28日 15:13:10 } catch (ex) { throw this.filename + “/parseResult() error: can’t parse to JSON.\n\n” + xhr.responseText; } break; case “XML” : result = xhr.responseXML; break; case “TEXT” : result = this.preFilter(xhr.responseText); break; default : throw this.filename + “/parseResult() error: unknown response type:” + responseType; } if (this.debugging.isDebugging) { var lf = this.debugging.linefeed, info = “[Response Result of " + responseType + " Format]” + lf + result; if (responseType === “JSON”) { info = “[Response Result of TEXT Format]” + lf + xhr.responseText + lf + lf + info; } this.displayDebuggingInfo(info, “result”); } return result; } }; var Ajax = Transport; Ajax.call = Transport.run; function objToJSONString(obj, filter){ return JSON.stringify(obj, filter); } function parseObjectToJSON(object, filter){ return JSON.parse(object, filter); } Ajax.onRunning = showLoader; Ajax.onComplete = hideLoader; function showLoader() { document.getElementsByTagName_r(‘body’).item(0).style.cursor = “wait”; if (top.frames['header-frame']) { top.frames['header-frame'].document.getElementByIdx_x(“load-div”).style.display = “block”; } else { var obj = document.getElementByIdx_x(‘loader’); if ( ! obj && process_request) { obj = document.createElement_x(“DIV”); obj.id = “loader”; obj.innerHTML = process_request; document.body.appendChild(obj); } } } function hideLoader() { document.getElementsByTagName_r(‘body’).item(0).style.cursor = “auto”; if (top.frames['header-frame']) { setTimeout(function(){top.frames['header-frame'].document.getElementByIdx_x(“load-div”).style.display = “none”}, 10); } else { try { var obj = document.getElementByIdx_x(“loader”); obj.style.display = ‘none’; document.body.removeChild(obj); } catch (ex) {} } }
|