ecshop里面jquery与transport.js文件冲突是众所周知的,这里提供的方案,不是最完美的,是在网上提出的解决方案的基础上整理的。
是这样的,保留原来的transport.js,发生冲突的页面调用修改过的transportGoods.js,这样就避免了修改所有js文件的麻烦;函数方面,保留原来的函数,调用出错的函数,重新复制一个,起个新的函数名。
不喜欢这种方式的,下面的可以忽略了,没有什么技术含量,总结了一下。
页面:goods.dwt
效果:放大镜
所用插件:jquery图片放大镜效果插件 jqzoom
症状一:jquery与transport.js文件冲突
思路分析:两者都定义了$,导致发生冲突
实施方案:详细的分析网上有很多,这里只上传已配置好的transport.js文件(文件名重命名为:transportGoods.js),感兴趣的百度下详细的配置。
解决步骤:
下载transportGoods.js到js目录下
在goods.dwt页面,适当的位置调用一下就好:
{insert_scripts files='transportGoods.js'}
至此,放大镜效果完美解决了。
症状二:在线购买失效,报错:
错误: goods.toJSONString is not a function
源文件:http://xxxxx/js/common.js
行:34
出错地方的代码:Ajax.call('flow.php?step=add_to_cart', 'goods=' + goods.toJSONString(), addToCartResponse, 'POST', 'JSON');
思路分析:goods.dwt页面调用的是修改后的transportGoods.js文件,导致toJSONString函数找不到。
解决步骤:
1、对比transport.js与transportGoods.js 的352行
legalParams = "JSON=" + params.toJSONString(); //transport.js
legalParams = "JSON=" + objToJSONString(params); //transportGoods.js
2、common.js文件的34行:
Ajax.call('flow.php?step=add_to_cart', 'goods=' + goods.toJSONString(), addToCartResponse, 'POST', 'JSON');
3、分析1、2中的红色代码区,修改common.js的34行为:
Ajax.call('flow.php?step=add_to_cart', 'goods=' + objToJSONString(goods), addToCartResponse, 'POST', 'JSON');
4、至此,证明方法可行,但是其他地方的Ajax.call就会出错,在线购买调用的是common.js里面的addToCart()函数,复制一份,重命名为:addToCartGoods(),修改里面的Ajax.call为步骤3中提到的。
5、修改goods.dwt页面,调用addToCart()的地方为addToCartGoods()
OK!
1 /** 2 * @file transport.js 3 * @description 用于支持AJAX的传输类。 4 * @author ECShop R&D Team ( http://www.ecshop.com/ ) 5 * @date 2007-03-08 Wednesday 6 * @license Licensed under the Academic Free License 2.1 http://www.opensource.org/licenses/afl-2.1.php 7 * @version 1.0.20070308 8 **/ 9 10 var Transport = 11 { 12 /* * 13 * 存储本对象所在的文件名。 14 * 15 * @static 16 */ 17 filename : "transportGoods.js", 18 19 /* * 20 * 存储是否进入调试模式的开关,打印调试消息的方式,换行符,调试用的容器的ID。 21 * 22 * @private 23 */ 24 debugging : 25 { 26 isDebugging : 0, 27 debuggingMode : 0, 28 linefeed : "", 29 containerId : 0 30 }, 31 32 /* * 33 * 设置调试模式以及打印调试消息方式的方法。 34 * 35 * @public 36 * @param {int} 是否打开调试模式 0:关闭,1:打开 37 * @param {int} 打印调试消息的方式 0:alert,1:innerHTML 38 * 39 */ 40 debug : function (isDebugging, debuggingMode) 41 { 42 this.debugging = 43 { 44 "isDebugging" : isDebugging, 45 "debuggingMode" : debuggingMode, 46 "linefeed" : debuggingMode ? "<br />" : "\n", 47 "containerId" : "dubugging-container" + new Date().getTime() 48 }; 49 }, 50 51 /* * 52 * 传输完毕后自动调用的方法,优先级比用户从run()方法中传入的回调函数高。 53 * 54 * @public 55 */ 56 onComplete : function () 57 { 58 }, 59 60 /* * 61 * 传输过程中自动调用的方法。 62 * 63 * @public 64 */ 65 onRunning : function () 66 { 67 }, 68 69 /* * 70 * 调用此方法发送HTTP请求。 71 * 72 * @public 73 * @param {string} url 请求的URL地址 74 * @param {mix} params 发送参数 75 * @param {Function} callback 回调函数 76 * @param {string} ransferMode 请求的方式,有"GET"和"POST"两种 77 * @param {string} responseType 响应类型,有"JSON"、"XML"和"TEXT"三种 78 * @param {boolean} asyn 是否异步请求的方式 79 * @param {boolean} quiet 是否安静模式请求 80 */ 81 run : function (url, params, callback, transferMode, responseType, asyn, quiet) 82 { 83 /* 处理用户在调用该方法时输入的参数 */ 84 params = this.parseParams(params); 85 transferMode = typeof(transferMode) === "string" 86 && transferMode.toUpperCase() === "GET" 87 ? "GET" 88 : "POST"; 89 90 if (transferMode === "GET") 91 { 92 var d = new Date(); 93 94 url += params ? (url.indexOf("?") === - 1 ? "?" : "&") + params : ""; 95 url = encodeURI(url) + (url.indexOf("?") === - 1 ? "?" : "&") + d.getTime() + d.getMilliseconds(); 96 params = null; 97 } 98 99 responseType = typeof(responseType) === "string" && ((responseType = responseType.toUpperCase()) === "JSON" || responseType === "XML") ? responseType : "TEXT"; 100 asyn = asyn === false ? false : true; 101 102 /* 处理HTTP请求和响应 */ 103 var xhr = this.createXMLHttpRequest(); 104 105 try 106 { 107 var self = this; 108 109 if (typeof(self.onRunning) === "function" && !quiet) 110 { 111 self.onRunning(); 112 } 113 114 xhr.open(transferMode, url, asyn); 115 116 if (transferMode === "POST") 117 { 118 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 119 } 120 121 if (asyn) 122 { 123 xhr.onreadystatechange = function () 124 { 125 if (xhr.readyState == 4) 126 { 127 switch ( xhr.status ) 128 { 129 case 0: 130 case 200: // OK! 131 /* 132 * If the request was to create a new resource 133 * (such as post an item to the database) 134 * You could instead return a status code of '201 Created' 135 */ 136 137 if (typeof(self.onComplete) === "function") 138 { 139 self.onComplete(); 140 } 141 142 if (typeof(callback) === "function") 143 { 144 callback.call(self, self.parseResult(responseType, xhr), xhr.responseText); 145 } 146 break; 147 148 case 304: // Not Modified 149 /* 150 * This would be used when your Ajax widget is 151 * checking for updated content, 152 * such as the Twitter interface. 153 */ 154 break; 155 156 case 400: // Bad Request 157 /* 158 * A bit like a safety net for requests by your JS interface 159 * that aren't supported on the server. 160 * "Your browser made a request that the server cannot understand" 161 */ 162 alert("XmlHttpRequest status: [400] Bad Request"); 163 break; 164 165 case 404: // Not Found 166 alert("XmlHttpRequest status: [404] \nThe requested URL "+url+" was not found on this server."); 167 break; 168 169 case 409: // Conflict 170 /* 171 * Perhaps your JavaScript request attempted to 172 * update a Database record 173 * but failed due to a conflict 174 * (eg: a field that must be unique) 175 */ 176 break; 177 178 case 503: // Service Unavailable 179 /* 180 * A resource that this request relies upon 181 * is currently unavailable 182 * (eg: a file is locked by another process) 183 */ 184 alert("XmlHttpRequest status: [503] Service Unavailable"); 185 break; 186 187 default: 188 alert("XmlHttpRequest status: [" + xhr.status + "] Unknow status."); 189 } 190 191 xhr = null; 192 } 193 } 194 if (xhr != null) xhr.send(params); 195 } 196 else 197 { 198 if (typeof(self.onRunning) === "function") 199 { 200 self.onRunning(); 201 } 202 203 xhr.send(params); 204 205 var result = self.parseResult(responseType, xhr); 206 //xhr = null; 207 208 if (typeof(self.onComplete) === "function") 209 { 210 self.onComplete(); 211 } 212 if (typeof(callback) === "function") 213 { 214 callback.call(self, result, xhr.responseText); 215 } 216 217 return result; 218 } 219 } 220 catch (ex) 221 { 222 if (typeof(self.onComplete) === "function") 223 { 224 self.onComplete(); 225 } 226 227 alert(this.filename + "/run() error:" + ex.description); 228 } 229 }, 230 231 /* * 232 * 如果开启了调试模式,该方法会打印出相应的信息。 233 * 234 * @private 235 * @param {string} info 调试信息 236 * @param {string} type 信息类型 237 */ 238 displayDebuggingInfo : function (info, type) 239 { 240 if ( ! this.debugging.debuggingMode) 241 { 242 alert(info); 243 } 244 else 245 { 246 247 var id = this.debugging.containerId; 248 if ( ! document.getElementById(id)) 249 { 250 div = document.createElement("DIV"); 251 div.id = id; 252 div.style.position = "absolute"; 253 div.style.width = "98%"; 254 div.style.border = "1px solid #f00"; 255 div.style.backgroundColor = "#eef"; 256 var pageYOffset = document.body.scrollTop 257 || window.pageYOffset 258 || 0; 259 div.style.top = document.body.clientHeight * 0.6 260 + pageYOffset 261 + "px"; 262 document.body.appendChild(div); 263 div.innerHTML = "<div></div>" 264 + "<hr style='height:1px;border:1px dashed red;'>" 265 + "<div></div>"; 266 } 267 268 var subDivs = div.getElementsByTagName("DIV"); 269 if (type === "param") 270 { 271 subDivs[0].innerHTML = info; 272 } 273 else 274 { 275 subDivs[1].innerHTML = info; 276 } 277 } 278 }, 279 280 /* * 281 * 创建XMLHttpRequest对象的方法。 282 * 283 * @private 284 * @return 返回一个XMLHttpRequest对象 285 * @type Object 286 */ 287 createXMLHttpRequest : function () 288 { 289 var xhr = null; 290 291 if (window.ActiveXObject) 292 { 293 var versions = ['Microsoft.XMLHTTP', 'MSXML6.XMLHTTP', 'MSXML5.XMLHTTP', 'MSXML4.XMLHTTP', 'MSXML3.XMLHTTP', 'MSXML2.XMLHTTP', 'MSXML.XMLHTTP']; 294 295 for (var i = 0; i < versions.length; i ++ ) 296 { 297 try 298 { 299 xhr = new ActiveXObject(versions); 300 break; 301 } 302 catch (ex) 303 { 304 continue; 305 } 306 } 307 } 308 else 309 { 310 xhr = new XMLHttpRequest(); 311 } 312 313 return xhr; 314 }, 315 316 /* * 317 * 当传输过程发生错误时将调用此方法。 318 * 319 * @private 320 * @param {Object} xhr XMLHttpRequest对象 321 * @param {String} url HTTP请求的地址 322 */ 323 onXMLHttpRequestError : function (xhr, url) 324 { 325 throw "URL: " + url + "\n" 326 + "readyState: " + xhr.readyState + "\n" 327 + "state: " + xhr.status + "\n" 328 + "headers: " + xhr.getAllResponseHeaders(); 329 }, 330 331 /* * 332 * 对将要发送的参数进行格式化。 333 * 334 * @private 335 * @params {mix} params 将要发送的参数 336 * @return 返回合法的参数 337 * @type string 338 */ 339 parseParams : function (params) 340 { 341 var legalParams = ""; 342 params = params ? params : ""; 343 344 if (typeof(params) === "string") 345 { 346 legalParams = params; 347 } 348 else if (typeof(params) === "object") 349 { 350 try 351 { 352 legalParams = "JSON=" + objToJSONString(params); 353 } 354 catch (ex) 355 { 356 alert("Can't stringify JSON!"); 357 return false; 358 } 359 } 360 else 361 { 362 alert("Invalid parameters!"); 363 return false; 364 } 365 366 if (this.debugging.isDebugging) 367 { 368 var lf = this.debugging.linefeed, 369 info = "[Original Parameters]" + lf + params + lf + lf 370 + "[Parsed Parameters]" + lf + legalParams; 371 372 this.displayDebuggingInfo(info, "param"); 373 } 374 375 return legalParams; 376 }, 377 378 /* * 379 * 对返回的HTTP响应结果进行过滤。 380 * 381 * @public 382 * @params {mix} result HTTP响应结果 383 * @return 返回过滤后的结果 384 * @type string 385 */ 386 preFilter : function (result) 387 { 388 return result.replace(/\xEF\xBB\xBF/g, ""); 389 }, 390 391 /* * 392 * 对返回的结果进行格式化。 393 * 394 * @private 395 * @return 返回特定格式的数据结果 396 * @type mix 397 */ 398 parseResult : function (responseType, xhr) 399 { 400 var result = null; 401 402 switch (responseType) 403 { 404 case "JSON" : 405 result = this.preFilter(xhr.responseText); 406 try 407 { 408 result = parseObjectToJSON(result); 409 } 410 catch (ex) 411 { 412 throw this.filename + "/parseResult() error: can't parse to JSON.\n\n" + xhr.responseText; 413 } 414 break; 415 case "XML" : 416 result = xhr.responseXML; 417 break; 418 case "TEXT" : 419 result = this.preFilter(xhr.responseText); 420 break; 421 default : 422 throw this.filename + "/parseResult() error: unknown response type:" + responseType; 423 } 424 425 if (this.debugging.isDebugging) 426 { 427 var lf = this.debugging.linefeed, 428 info = "[Response Result of " + responseType + " Format]" + lf 429 + result; 430 431 if (responseType === "JSON") 432 { 433 info = "[Response Result of TEXT Format]" + lf 434 + xhr.responseText + lf + lf 435 + info; 436 } 437 438 this.displayDebuggingInfo(info, "result"); 439 } 440 441 return result; 442 } 443 }; 444 445 /* 定义两个别名 */ 446 var Ajax = Transport; 447 Ajax.call = Transport.run; 448 449 /* 450 json.js 451 2007-03-06 452 453 Public Domain 454 455 This file adds these methods to JavaScript: 456 457 array.toJSONString() 458 boolean.toJSONString() 459 date.toJSONString() 460 number.toJSONString() 461 object.toJSONString() 462 string.toJSONString() 463 These methods produce a JSON text from a JavaScript value. 464 It must not contain any cyclical references. Illegal values 465 will be excluded. 466 467 The default conversion for dates is to an ISO string. You can 468 add a toJSONString method to any date object to get a different 469 representation. 470 471 string.parseJSON(filter) 472 This method parses a JSON text to produce an object or 473 array. It can throw a SyntaxError exception. 474 475 The optional filter parameter is a function which can filter and 476 transform the results. It receives each of the keys and values, and 477 its return value is used instead of the original value. If it 478 returns what it received, then structure is not modified. If it 479 returns undefined then the member is deleted. 480 481 Example: 482 483 // Parse the text. If a key contains the string 'date' then 484 // convert the value to a date. 485 486 myData = text.parseJSON(function (key, value) { 487 return key.indexOf('date') >= 0 ? new Date(value) : value; 488 }); 489 490 It is expected that these methods will formally become part of the 491 JavaScript Programming Language in the Fourth Edition of the 492 ECMAScript standard in 2008. 493 */ 494 495 // Augment the basic prototypes if they have not already been augmented. 496 /* 497 if ( ! Object.prototype.toJSONString) { 498 Array.prototype.toJSONString = function () { 499 var a = ['['], // The array holding the text fragments. 500 b, // A boolean indicating that a comma is required. 501 i, // Loop counter. 502 l = this.length, 503 v; // The value to be stringified. 504 505 function p(s) { 506 507 // p accumulates text fragments in an array. It inserts a comma before all 508 // except the first fragment. 509 510 if (b) { 511 a.push(','); 512 } 513 a.push(s); 514 b = true; 515 } 516 517 // For each value in this array... 518 519 for (i = 0; i < l; i ++) { 520 v = this; 521 switch (typeof v) { 522 523 // Values without a JSON representation are ignored. 524 525 case 'undefined': 526 case 'function': 527 case 'unknown': 528 break; 529 530 // Serialize a JavaScript object value. Ignore objects thats lack the 531 // toJSONString method. Due to a specification error in ECMAScript, 532 // typeof null is 'object', so watch out for that case. 533 534 case 'object': 535 if (v) { 536 if (typeof v.toJSONString === 'function') { 537 p(v.toJSONString()); 538 } 539 } else { 540 p("null"); 541 } 542 break; 543 544 // Otherwise, serialize the value. 545 546 default: 547 p(v.toJSONString()); 548 } 549 } 550 551 // Join all of the fragments together and return. 552 553 a.push(']'); 554 return a.join(''); 555 }; 556 557 Boolean.prototype.toJSONString = function () { 558 return String(this); 559 }; 560 561 Date.prototype.toJSONString = function () { 562 563 // Ultimately, this method will be equivalent to the date.toISOString method. 564 565 function f(n) { 566 567 // Format integers to have at least two digits. 568 569 return n < 10 ? '0' + n : n; 570 } 571 572 return '"' + this.getFullYear() + '-' + 573 f(this.getMonth() + 1) + '-' + 574 f(this.getDate()) + 'T' + 575 f(this.getHours()) + ':' + 576 f(this.getMinutes()) + ':' + 577 f(this.getSeconds()) + '"'; 578 }; 579 580 Number.prototype.toJSONString = function () { 581 582 // JSON numbers must be finite. Encode non-finite numbers as null. 583 584 return isFinite(this) ? String(this) : "null"; 585 }; 586 587 Object.prototype.toJSONString = function () { 588 var a = ['{'], // The array holding the text fragments. 589 b, // A boolean indicating that a comma is required. 590 k, // The current key. 591 v; // The current value. 592 593 function p(s) { 594 595 // p accumulates text fragment pairs in an array. It inserts a comma before all 596 // except the first fragment pair. 597 598 if (b) { 599 a.push(','); 600 } 601 a.push(k.toJSONString(), ':', s); 602 b = true; 603 } 604 605 // Iterate through all of the keys in the object, ignoring the proto chain. 606 607 for (k in this) { 608 if (this.hasOwnProperty(k)) { 609 v = this[k]; 610 switch (typeof v) { 611 612 // Values without a JSON representation are ignored. 613 614 case 'undefined': 615 case 'function': 616 case 'unknown': 617 break; 618 619 // Serialize a JavaScript object value. Ignore objects that lack the 620 // toJSONString method. Due to a specification error in ECMAScript, 621 // typeof null is 'object', so watch out for that case. 622 623 case 'object': 624 if (this !== window) 625 { 626 if (v) { 627 if (typeof v.toJSONString === 'function') { 628 p(v.toJSONString()); 629 } 630 } else { 631 p("null"); 632 } 633 } 634 break; 635 default: 636 p(v.toJSONString()); 637 } 638 } 639 } 640 641 // Join all of the fragments together and return. 642 643 a.push('}'); 644 return a.join(''); 645 }; 646 647 (function (s) { 648 649 // Augment String.prototype. We do this in an immediate anonymous function to 650 // avoid defining global variables. 651 652 // m is a table of character substitutions. 653 654 var m = { 655 '\b': '\\b', 656 '\t': '\\t', 657 '\n': '\\n', 658 '\f': '\\f', 659 '\r': '\\r', 660 '"' : '\\"', 661 '\\': '\\\\' 662 }; 663 664 s.parseJSON = function (filter) { 665 666 // Parsing happens in three stages. In the first stage, we run the text against 667 // a regular expression which looks for non-JSON characters. We are especially 668 // concerned with '()' and 'new' because they can cause invocation, and '=' 669 // because it can cause mutation. But just to be safe, we will reject all 670 // unexpected characters. 671 672 try { 673 if (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/. 674 test(this)) { 675 676 // In the second stage we use the eval function to compile the text into a 677 // JavaScript structure. The '{' operator is subject to a syntactic ambiguity 678 // in JavaScript: it can begin a block or an object literal. We wrap the text 679 // in parens to eliminate the ambiguity. 680 681 var j = eval('(' + this + ')'); 682 683 // In the optional third stage, we recursively walk the new structure, passing 684 // each name/value pair to a filter function for possible transformation. 685 686 if (typeof filter === 'function') { 687 688 function walk(k, v) { 689 if (v && typeof v === 'object') { 690 for (var i in v) { 691 if (v.hasOwnProperty(i)) { 692 v = walk(i, v); 693 } 694 } 695 } 696 return filter(k, v); 697 } 698 699 j = walk('', j); 700 } 701 return j; 702 } 703 } catch (e) { 704 705 // Fall through if the regexp test fails. 706 707 } 708 throw new SyntaxError("parseJSON"); 709 }; 710 711 s.toJSONString = function () { 712 713 // If the string contains no control characters, no quote characters, and no 714 // backslash characters, then we can simply slap some quotes around it. 715 // Otherwise we must also replace the offending characters with safe 716 // sequences. 717 718 // add by weberliu @ 2007-4-2 719 var _self = this.replace("&", "%26"); 720 721 if (/["\\\x00-\x1f]/.test(this)) { 722 return '"' + _self.replace(/([\x00-\x1f\\"])/g, function(a, b) { 723 var c = m; 724 if (c) { 725 return c; 726 } 727 c = b.charCodeAt(); 728 return '\\u00' + 729 Math.floor(c / 16).toString(16) + 730 (c % 16).toString(16); 731 }) + '"'; 732 } 733 return '"' + _self + '"'; 734 }; 735 })(String.prototype); 736 } 737 */ 738 739 Ajax.onRunning = showLoader; 740 Ajax.onComplete = hideLoader; 741 742 /* * 743 * 显示载入信息 744 */ 745 function showLoader() 746 { 747 document.getElementsByTagName('body').item(0).style.cursor = "wait"; 748 749 if (top.frames['header-frame']) 750 { 751 top.frames['header-frame'].document.getElementById("load-div").style.display = "block"; 752 } 753 else 754 { 755 var obj = document.getElementById('loader'); 756 757 if ( ! obj && process_request) 758 { 759 obj = document.createElement("DIV"); 760 obj.id = "loader"; 761 obj.innerHTML = process_request; 762 763 document.body.appendChild(obj); 764 } 765 } 766 } 767 768 /* * 769 * 隐藏载入信息 770 */ 771 function hideLoader() 772 { 773 document.getElementsByTagName('body').item(0).style.cursor = "auto"; 774 if (top.frames['header-frame']) 775 { 776 setTimeout(function(){top.frames['header-frame'].document.getElementById("load-div").style.display = "none"}, 10); 777 } 778 else 779 { 780 try 781 { 782 var obj = document.getElementById("loader"); 783 obj.style.display = 'none'; 784 document.body.removeChild(obj); 785 } 786 catch (ex) 787 {} 788 } 789 } 790 791 function objToJSONString(obj, filter){ 792 return JSON.stringify(obj, filter); 793 } 794 795 function parseObjectToJSON(object, filter){ 796 return JSON.parse(object, filter); 797 }
成功解决!