如何从html中卸载javascript?

如何从html中卸载javascript?,javascript,dom,Javascript,Dom,如何从DOM卸载JavaScript资源及其所有已定义对象 我正在开发一个简单的框架,可以将html片段加载到“主”html中。每个片段都是自包含的,可能包括对附加JS和CSS文件的引用。JS和CSS资源被解析并动态添加到html中。当片段从DOM中删除/替换时,我想删除它的JS和CSS 如果删除下面示例中的script元素,page1.js中定义的函数仍然可用 <html> <head> <script src="page1.js" type="tex

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

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

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

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

也许你需要考虑有条件地加载它,而不是有条件地卸载它…

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

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

// unload all resources
cleanup();
另一种方法是为片段使用模块化的对象结构,这些片段会自行清理。这需要稍高的开销,但可能是值得的,因为它使代码更易于阅读和维护:

// 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.
这是不可能做到的

执行脚本时,函数定义将添加到全局
窗口
对象中。函数可能附加了一些调试符号,指示函数的来源,但这些信息对脚本不可用


实现这种功能的唯一方法是在脚本中创建一个伪名称空间,然后在使用完该名称空间后扔掉整个名称空间。然而,这个问题向我暗示,你正试图以错误的方式做某事。也许详细说明您的场景有助于我们提供替代解决方案。

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

ie:
myobj={}

因此,如果您知道在特定的include中创建了哪些对象,这一点都不难

另一方面,如果您不知道在特定的include中创建了什么对象,那么就没有一个mechansim可以找到-您不能让Javascript告诉您在特定的include中定义了什么


然而,我想说的是,如果您不知道某个特定javascript文件中加载了哪些对象,那么在加载它(您应该始终对站点中的代码有一个合理的了解)或尝试手动卸载它时,您可能没有给自己带来任何好处(如果你不知道它是干什么的,那就意味着它是第三方的,这意味着手动取消它很可能会破坏一切)。

我自己也在研究类似的东西,我想我会发布我的发现

  • 在js文件中将你的东西包装在一个全局名称空间中,这样它就可以很容易地被删除 var stuff={blabla:1,方法:function(){}

  • 当您需要摆脱它时,只需设置stuff={},甚至设置null

  • 从页面中删除脚本标记
  • ***如果您使用requirejs-

    注意:只要您不从任何其他地方引用名称空间内的模块,所有内容都将由GC收集,您就可以开始了

    我想出了一个诀窍。我想在这里找到答案,我刚刚意识到了一个完美的诀窍,可以在不卸载java脚本的情况下做到这一点。只需在
    main
    页面的java脚本中创建一个全局变量,如
    currentPage
    ,然后在加载页面时将页面名称分配给
    currentPage
    。然后在每隔一个
    .js
    文件中使用
    $('document').ajaxComplete()
    代替
    $('document')。ready()
    在每个
    $('document')内的第一行添加if语句。ajaxComplete()
    函数。将其设置为check
    currentPage
    变量等于一个新的页面名称。在if语句中添加所有其他事件。我不太懂英语,所以请检查我的代码。这是我在这里的第一个答案。如果我犯了一些错误,我很抱歉

    main.html

    <body>
        <div id='container></div>
        <button id="load1">
        <button id="load1">
    </body>
    
    页面2.html

    <body>
        <button id="test1">
        <button id="test2">
    </body>
    
    我在每个脚本中注释了一个按钮,以检查该按钮是否仍然具有旧脚本的效果


    您可以将它们设置为=null

        function fnc1 (){
    
        }
    
        window.fnc1  = null
        //or
        window["fnc1"]  = null
    

    可能,但需要手动定义清理,可能会导致内存泄漏。我需要此解决方案来实现一个简单的框架im编写,该框架允许单个html动态加载链接到其他JS&CSS资源的html片段。替换片段时,我需要卸载其JS和CSS上下文。@Totach:对,但这是摆脱这些变量的唯一方法。在这样做时需要考虑分离事件等。这只是一个简单的例子。我尝试了你的解决方案,但出于一些奇怪的原因-无法删除对象!?(firefox中返回false)。注意,脚本是通过创建脚本标记动态加载的。有什么想法吗?非常感谢!@Totach:我使用Firebug控制台尝试了以下操作:
    var foo='bar',cleanup=function(){delete window.foo;delete window.cleanup;};cleanup();
    并且它的工作方式与预期的一样。您的确切错误消息是什么?在控制台中,它也适用于我。但是在html中,我通过创建脚本标记并将其附加到head元素(使用JavaScript)来加载脚本。当我尝试删除附加脚本添加的对象时,“false”返回,并且对象保持定义状态。我注意到,如果使用名称空间对象,则无法删除名称空间对象,但可以删除在名称空间上定义的对象…(再次感谢)谢谢-将对象添加到名称空间,然后将其删除似乎是最好的方法。@Totach:使用这种方法时,内存泄漏仍然是一个问题,但您可能已经解决了。如果您以客观的方式看待它,您正在尝试做与中相同的事情:…iFrame似乎是一种相当正常的方法,可以像我一样做很多事情“关于清理,这是可能的。@Ravindra:我不能使用iFrames,因为我不知道片段的尺寸,另外,片段需要与
    var currentPage = "";
    
    $(document).ready(function () {
        $('#load1').click(function () {
            loadSource('page1', 'body');
        });
        $('#load2').click(function () {
            loadSource('page2', 'body');
        });
    });
    
    function loadSource( page, element){
        currentPage = page;
        $('#container').load('views/' + page + '.php', element);
        $.getScript('js/' + page + '.js');
        $('#css').prop('disabled', true).remove();
        $('head').append('<link rel="stylesheet" href="css/' + page + '.css" type="text/css" />');
    }
    
    <body>
        <button id="test1">
        <button id="test2">
    </body>
    
    $(document).ajaxComplete(function () {
        if(currentPage == 'page1'){
            /*$('#test1').click(function () {
                console.log('page1');
            });*/
            $('#test2').click(function () {
                console.log('page1');
            });
        }
    });
    
    <body>
        <button id="test1">
        <button id="test2">
    </body>
    
    $(document).ajaxComplete(function () {
        if(currentPage == 'page2'){
            $('#test1').click(function () {
                console.log('page2');
            });
            /*$('#test2').click(function () {
                console.log('page2');
            });*/
        }
    });
    
        function fnc1 (){
    
        }
    
        window.fnc1  = null
        //or
        window["fnc1"]  = null