首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

ExtJS 動態載入與卸載 JS 檔案實作指南

     編輯:程式設計疑難解答

需求場景

首頁載入 main.js,點擊按鈕才動態載入 module.js;關閉模組時需卸載已載入的 JS,避免記憶體洩漏與命名衝突。

動態載入 JS 的標準做法

Ext.define('MyApp.controller.Main', {
    extend: 'Ext.app.Controller',
    init: function() {
        this.control({
            'button#loadModule': {
                click: 'onLoadModuleClick'
            }
        });
    },
    onLoadModuleClick: function(btn) {
        // 方法 1:Ext.Loader 載入類別(推薦用於 Ext 類別)
        Ext.require('MyApp.module.Panel', function() {
            var win = Ext.create('MyApp.module.Panel');
            win.show();
        });

        // 方法 2:通用 JS 載入(非 Ext 類別或第三方庫)
        var script = document.createElement('script');
        script.src = 'module.js?v=' + new Date().getTime(); // 時間戳防快取
        script.onload = function() {
            // 載入完成後初始化模組
            if (window.initModule) window.initModule();
        };
        document.head.appendChild(script);
    }
});

「卸載 JS」的誤區與替代方案

瀏覽器無法真正卸載已執行的 JavaScript 程式碼(無法從 V8/SpiderMonkey 記憶體中移除函式定義)。常見替代策略:

  1. 命名空間隔離:模組所有變數/函式掛在唯一命名空間下,卸載時 delete MyApp.Module 釋放引用,等待 GC 回收。
  2. 事件監聽器清理:模組啟動時綁定的事件(addEventListener, Ext 事件)必須在關閉時 removeEventListener/un。
  3. DOM 元素移除:動態建立的元件 destroy(),移除對應 DOM 節點。
  4. 時間戳/版本號強制刷新:重新載入時 src='module.js?v=2' 獲取最新版本,舊版本程式碼仍在記憶體但不再被引用。
  5. iframe 隔離(極端情況):將模組放在獨立 <iframe>,關閉時移除 iframe,瀏覽器會回收其完整 JS 上下文。

防止快取的 Meta 標籤(慎用)

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />

此設定會導致所有資源(CSS、圖片、API)不快取,嚴重影響效能。建議僅在開發環境或針對特定 JS 檔案加時間戳。

完整範例:動態載入與清理

Ext.define('MyApp.module.DynamicLoader', {
    singleton: true,
    loadModule: function(moduleName, callback) {
        var url = moduleName + '.js?v=' + Date.now();
        var script = document.createElement('script');
        script.src = url;
        script.onload = function() {
            Ext.callback(callback);
        };
        document.head.appendChild(script);
    },
    unloadModule: function(moduleNamespace) {
        // 1. 銷毀 Ext 元件
        if (moduleNamespace && moduleNamespace.destroyAll) {
            moduleNamespace.destroyAll();
        }
        // 2. 移除事件監聽(需模組自行暴露清理函式)
        if (moduleNamespace && moduleNamespace.cleanup) {
            moduleNamespace.cleanup();
        }
        // 3. 刪除命名空間引用
        if (moduleNamespace) {
            // 假設掛在 window.MyApp.Modules[moduleName]
            delete window.MyApp.Modules[moduleName];
        }
    }
});
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved