如果我們用 jQuery 在開發網頁,那麼 jQuery 應該也一定只載入一次,偏偏就有第三方合作廠商,完全沒有在管客戶是不是會出問題?檢查也不做,愛載就載,例如:6763 的站內付 2.0,用他們的 Web JS SDK
初始付款頁面的時候強制載入了 jQuery 3.4.1,如果我們的網頁本身就已經載入 jQuery 了,就會導致重複載入,那會發生什麼事?
問題
jQuery 除了選擇器之外,還有另一個很重要的功能 - extend,架構在 jQuery 之上的擴充元件,幾乎沒有不用 extend 的,而重複載入 jQuery 會導致使用 extend 的擴充元件全數失效,底下我弄個範例,分別在 $.fn.extend() 及 $.extend() 各擴充一個方法。
正常的話,瀏覽網頁應該會看到 ABC: abc
的字樣。
可是,當我們再載入一次 jQuery 之後,網頁不僅空白一片,Console 還出現錯誤訊息,告訴我們方法不存在,因為整個 jQuery 被重置了。
解決方法
目前我用的解法是「讓 jQuery 唯讀
」,我們呼叫 jQuery 函式可以透過兩個全域變數 window.$
及 window.jQuery
,我利用 Object.defineProperty() 在我們自己版本的 jQuery 載入後,重新定義 window.$ 及 window.jQuery 的 get()
與 set()
,這樣 jQuery 就唯讀了。
不過這也要注意,第三方合作廠商是不是也有自己擴充元件,有的話這個解決方法就不行了,以我目前遇到的狀況是剛好沒有。
如果我是第三方合作廠商
如果是我做為第三方合作廠商,其實大可在 API 文件中講好需要 jQuery 哪一個版本?我自己就不載入了,當沒有 jQuery 可以用或不是特定版本的時候印個錯誤訊息,又或者我們自己獨立載入,與客戶的環境切開,我們來看要怎麼做?
僅檢查 jQuery
- 檢查有沒有 window.jQuery?有則跳至 2.,無則印出錯誤訊息。
- 檢查 window.jQuery 是否為特定版本?是則往下執行,無則印出錯誤訊息。
程式碼如下,相關說明寫在註解中。
(function () {
// 動態載入 script
var loadScript = function (src, onload) {
var scriptElm = document.createElement("script");
scriptElm.onload = onload;
scriptElm.src = src;
document.body.appendChild(scriptElm);
}
if (window.jQuery) {
var version = window.jQuery.fn.jquery.split(".").reduce((ver, next) => ver * 10 + parseInt(next), 0);
if (version < 350) {
console.error("jQuery version is not 3.5.0+")
} else {
// 載入其他依賴 jQuery 的程式碼
loadScript("my.js");
}
} else {
console.error("jQuery is not loaded")
}
})();
獨立載入,與客戶的環境切開。
- 檢查目前網頁中是否已有 jQuery?有則做保留還原,無則直接載入。
- 建立自己的 jQuery Alias,不要使用預設的 window.$ 及 window.jQuery。
底下是程式碼,相關說明寫在註解中。
(function () {
// 動態載入 script
var loadScript = function (src, onload) {
var scriptElm = document.createElement("script");
scriptElm.onload = onload;
scriptElm.src = src;
document.body.appendChild(scriptElm);
}
if (window.jQuery) {
// 保留原本的 jQuery
var __jq = window.jQuery;
var __$ = window.$;
// 載入 jQuery
loadScript("https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js", function () {
// 建立自己的 jQuery 別名
window._chef_jQuery = window.jQuery;
window._chef_$ = window.$;
// 還原原本的 jQuery
window.jQuery = __jq;
window.$ = __$;
// 載入其他依賴 jQuery 的程式碼
loadScript("my.js");
});
} else {
loadScript("https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js", function () {
window._chef_jQuery = window.jQuery;
window._chef_$ = window.$;
loadScript("my.js");
});
}
})();
// my.js
console.log("my.js loaded")
// 使用自訂的 jQuery 別名
if (window._chef_jQuery) {
console.log("_chef_jQuery load successfully");
} else {
console.log("_chef_jQuery load failed");
}
以上,這次被 6763 - 站內付 2.0 搞到的解決方法分享給大家,希望對用 jQuery 開發網頁的朋友有一點幫助,真覺得浪費我的時間。