如何从 html 中卸载 javascript?

IT技术 javascript dom
2021-02-20 17:30:56

如何从 DOM 卸载 JavaScript 资源及其所有定义的对象?

我正在开发一个简单的框架,可以将 html 片段加载到“主”html 中。每个片段都是自包含的,可能包含对其他 JS 和 CSS 文件的引用。JS 和 CSS 资源被解析并动态添加到 html。当片段从 DOM 中删除/替换时,我想删除它的 JS 和 CSS。

如果我删除下面示例中的脚本元素,page1.js 中定义的函数仍然可用。

<html>
  <head>
    <script src="page1.js" type="text/javascript"></script>
  </head>
<body>
...

有没有办法从 DOM 中卸载 page1.js 对象?

========我使用的测试代码 ========

我尝试了我在下面的评论中得到的建议;使用清理功能删除添加的对象 - 但即使这样也会失败。我用于测试的来源:

<html>
<head>
<script type="text/javascript">
    function loadJSFile(){
        var scriptTag = document.createElement("script");
        scriptTag.setAttribute("type", "text/javascript");
        scriptTag.setAttribute("src", "simple.js");

        var head = document.getElementsByTagName("head")[0];
        head.appendChild(scriptTag);
    }

    function unloadJSFile(){            
        delete window.foo;
        delete window.cleanup;
        alert("cleanedup. typeof window.foo is " + (typeof window.foo));
    }
</script>
</head>
<body>

  Hello JavaScript Delete

  <br/>
  <button onclick="loadJSFile();">Click to load JS</button>
  <br/>
  <button onclick="foo();">call foo()</button>
  <br/>
  <button onclick="unloadJSFile();">Click to unload JS</button>

</body>
</html>

simple.js 源代码:

var foo = function(){
    alert("hello from foo");
}
6个回答

这是不可能的。

执行脚本时,函数定义会添加到全局window对象中。可能有附加到函数的调试符号指示函数的来源,但脚本无法使用此信息。

关于实现这样的事情的唯一方法是在脚本中创建一个伪命名空间,然后在完成后丢弃整个命名空间。但是,这个问题向我暗示您正试图以错误的方式做某事。也许详细说明您的场景将有助于我们提供替代解决方案。

谢谢 - 将对象添加到命名空间然后删除它似乎是最好的方法。
2021-04-17 17:30:56
@Totach:使用这种方法时,内存泄漏仍然是一个问题,但您可能已经解决了这个问题。
2021-05-04 17:30:56

也许您需要考虑有条件地加载它而不是有条件地卸载它...

不,那是不可能的。您可以构建一个简单的清理函数来删除该文件中定义的所有变量:

var foo = 'bar';
var cleanup = function () {
    delete window.foo;
    delete window.cleanup;
};

// unload all resources
cleanup();

另一种方法是为您的片段使用module化对象结构,然后自行清理。这涉及稍高的开销,但可能是值得的,因为它使代码更易于阅读和维护:

// creates the object using the second parameter as prototype.
// .create() is used as constructor
GlobalModuleHandlerThingy.addModule('my_module', {
    create: function () {
        this.foo = 'bar';
        return this;
    },
    foo: null,
    destroy: function () {
        // unload events, etc.
    }
});

GlobalModuleHandlerThingy.getModule('my_module').foo; // => bar
GlobalModuleHandlerThingy.unloadModule('my_module'); // calls .destroy() on the module and removes it.
@Totach:我使用 firebugs 控制台尝试了以下操作:var foo = 'bar', cleanup = function () { delete window.foo; delete window.cleanup; }; cleanup();它按预期工作。你的确切错误信息是什么?
2021-04-22 17:30:56
@Totach:是的,但这是摆脱这些变量的唯一方法。这样做时需要考虑分离事件等。这只是一个简单的例子。
2021-04-29 17:30:56
可能但需要手动定义清理并可能导致内存泄漏。我需要这个解决方案来编写一个简单的框架,它使单个 html 能够动态加载链接到其他 JS 和 CSS 资源的 html 片段。当片段被替换时,我需要卸载它们的 JS 和 CSS 上下文。
2021-05-03 17:30:56
我尝试了您的解决方案,但出于某种奇怪的原因-无法删除对象!?(在 Firefox 中返回 false)。请注意,脚本是通过创建脚本标记动态加载的。任何的想法?非常感谢!
2021-05-09 17:30:56
在控制台中它也适用于我。但在 html 中,我通过创建脚本标记加载脚本并将其附加到 head 元素(使用 JavaScript)。当我尝试删除由附加脚本添加的对象时,返回“false”并且对象保持定义。我注意到的是,如果我使用命名空间对象,则不能删除命名空间对象,但可以删除命名空间上定义的对象......(再次感谢)
2021-05-09 17:30:56

如果您需要卸载特定对象,这相当简单:只需将其设置为 {}

IE: myobj = {};

因此,如果您知道在特定包含中创建了哪些对象,那根本就不难。

另一方面,如果您不知道在特定包含中创建了哪些对象,则没有机制可以找出 - 您不能要求 Javascript 告诉您在特定包含中定义了什么。

但是,我想说的是,如果您不知道在特定的 javascript 文件中加载了哪些对象,那么您可能对加载它没有任何帮助(您应该始终对代码在您的站点中的作用有一个合理的了解) , 或者尝试手动卸载它(如果您不知道它是做什么的,这意味着它是第三方包含的,这意味着手动取消它可能会破坏它)。

它也可以通过函数来​​完成: function name()={}
2021-04-18 17:30:56

你可以让它们 = null

    function fnc1 (){

    }

    window.fnc1  = null
    //or
    window["fnc1"]  = null