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!
View Code
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[i]); 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[i]; 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[i] = walk(i, v[i]); 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[b]; 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 }
成功解決!
