如何从 html 中卸载 javascript?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4365062/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to unload a javascript from an html?
提问by Totach
How can I unload a JavaScript resource with all its defined objects from the DOM?
如何从 DOM 卸载 JavaScript 资源及其所有定义的对象?
Im developing a simple framework that enables to load html fragments into a "main" html. Each fragment is self contained and may include references to additional JS and CSS files. The JS and CSS resources are parsed and dynamically added to the html. When the fragment is removed/replaced from the DOM I want to remove its JS and CSS.
我正在开发一个简单的框架,可以将 html 片段加载到“主”html 中。每个片段都是自包含的,并且可能包含对其他 JS 和 CSS 文件的引用。JS 和 CSS 资源被解析并动态添加到 html。当片段从 DOM 中删除/替换时,我想删除它的 JS 和 CSS。
If I remove the script element in the example below, the functions defined in page1.js are still available.
如果我删除下面示例中的脚本元素,page1.js 中定义的函数仍然可用。
<html>
<head>
<script src="page1.js" type="text/javascript"></script>
</head>
<body>
...
Is there a way to unload page1.js objects from the DOM?
有没有办法从 DOM 中卸载 page1.js 对象?
========= The test code I use =======
========我使用的测试代码 ========
I tried the advice i got in the comments below; to delete the added objects using a cleanup function - but even this fails. The sources i used for testing:
我尝试了我在下面的评论中得到的建议;使用清理功能删除添加的对象 - 但即使这样也会失败。我用于测试的来源:
<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 source:
simple.js 源代码:
var foo = function(){
alert("hello from foo");
}
回答by cdhowie
This cannot be done.
这是无法做到的。
When a script is executed, function definitions are added to the global window
object. There may be debugging symbols attached to the function that indicate where the function came from, but this information is not available to scripts.
执行脚本时,函数定义会添加到全局window
对象中。可能有调试符号附加到函数,指示函数来自哪里,但此信息对脚本不可用。
About the only way you could achieve something like this would be to create a pseudo-namespace in the script and then throw away that whole namespace when you are done with it. However, this question hints to me that you are trying to do something the wrong way. Perhaps elaborating on your scenario would help us provide alternate solutions.
关于实现这样的事情的唯一方法是在脚本中创建一个伪命名空间,然后在完成后丢弃整个命名空间。但是,这个问题向我暗示您正试图以错误的方式做某事。也许详细说明您的场景将有助于我们提供替代解决方案。
回答by jwueller
No, that is not possible. You could build a simple cleanup function that removes all variables that were defined in that file:
不,那是不可能的。您可以构建一个简单的清理函数来删除该文件中定义的所有变量:
var foo = 'bar';
var cleanup = function () {
delete window.foo;
delete window.cleanup;
};
// unload all resources
cleanup();
Another approach would be to use a modular object structure for your fragments, that clean up after themselves. That involves a slightly higher overhead but is probably worth it, as it makes the code much easier to read and maintain:
另一种方法是为您的片段使用模块化对象结构,然后自行清理。这涉及稍高的开销,但可能是值得的,因为它使代码更易于阅读和维护:
// 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.
回答by Rob
perhaps you need to consider conditionally loading it rather than conditionally unloading it...
也许您需要考虑有条件地加载它而不是有条件地卸载它...
回答by hossein sedighian
you can make them = null
你可以让它们 = null
function fnc1 (){
}
window.fnc1 = null
//or
window["fnc1"] = null
回答by Spudley
If you need to unload a specific object, it's fairly easy: just set it to {}
如果您需要卸载特定对象,这很容易:只需将其设置为 {}
ie: myobj = {};
IE: myobj = {};
So if you know what objects are created in a particular include, it won't be hard at all.
因此,如果您知道在特定包含中创建了哪些对象,那根本就不难。
On the other hand, if you don't know what objects are created in a particular include, there isn't a mechansim to find out - you can't ask Javascript to tell you what was defined in a particular include.
另一方面,如果您不知道在特定包含中创建了哪些对象,则没有机制可以找出 - 您不能要求 Javascript 告诉您在特定包含中定义了什么。
However, I would say that if you don't know what objects are being loaded in a particular javascript file, you're probably not doing yourself any favours in loading it (you should always have a reasonable idea what code does in your site), or in trying to unload it manually (if you don't know what it does, that implies its a third party include, which means that unsetting it manually is likely to break things).
但是,我想说的是,如果您不知道在特定的 javascript 文件中加载了哪些对象,那么您可能对加载它没有任何帮助(您应该始终对代码在您的站点中的作用有一个合理的了解) ,或者尝试手动卸载它(如果您不知道它是做什么的,这意味着它是第三方包含的,这意味着手动取消它可能会破坏事物)。
回答by Pavdro
Was researching for something like that myself and thought I'll post my findings
我自己正在研究类似的东西,并认为我会发布我的发现
Wrap your stuff in a global namespace in js file so it can be removed easily, ie var stuff = { blabla: 1, method: function(){} };
When you need to get rid of it, simply set stuff = {}, or null even
- Remove script tag from page
将您的东西包装在 js 文件中的全局命名空间中,以便可以轻松删除它,即 var stuff = { blabla: 1, method: function(){} };
当您需要摆脱它时,只需设置 stuff = {},甚至为 null
- 从页面中删除脚本标签
*** If you use requirejs - require js remove definition to force reload
*** 如果您使用 requirejs -需要 js 删除定义以强制重新加载
Note: as long as you don't reference modules inside the namespace from anywhere else everything will be collected by GC and you are good to go.
注意:只要您不从其他任何地方引用命名空间内的模块,GC 就会收集所有内容,您就可以开始了。
回答by waruna udayanga
I figured a trick for this. I was wondering here days finding an answer for this and I just realized a perfect trick to do this without trying to unload the java Script. only you have to do is create a global variable like
currentPage
in yourmain
page's java script and when you loading the page assign the page name tocurrentPage
. then in every other.js
file use$('document').ajaxComplete()
insted of$('document').ready()
add an if statement as first line inside every$('document').ajaxComplete()
function. set it to checkcurrentPage
variable equals to a new page name. add all other events inside if statement. i don't know English very well so check my code. and This is my first answer here so sorry if i make some mistakes.
为此我想了个窍门。我想在这里几天找到答案,我刚刚意识到一个完美的技巧来做到这一点,而无需尝试卸载 java 脚本。唯一要做的就是创建一个全局变量,就像
currentPage
在main
页面的 java 脚本中一样,并在加载页面时将页面名称分配给currentPage
. 然后在每个其他.js
文件中使用$('document').ajaxComplete()
insted$('document').ready()
添加一个 if 语句作为每个$('document').ajaxComplete()
函数内的第一行。将其设置为检查currentPage
变量是否等于新页面名称。在 if 语句中添加所有其他事件。我不太懂英语所以检查我的代码。这是我在这里的第一个答案,如果我犯了一些错误,很抱歉。
main.html
主文件
<body>
<div id='container></div>
<button id="load1">
<button id="load1">
</body>
main.js
主文件
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" />');
}
all of my pages scripts and styles are in seperate folders views, js, css.
我所有的页面脚本和样式都在单独的文件夹视图、js、css 中。
page1.html
页面1.html
<body>
<button id="test1">
<button id="test2">
</body>
page1.js
页面1.js
$(document).ajaxComplete(function () {
if(currentPage == 'page1'){
/*$('#test1').click(function () {
console.log('page1');
});*/
$('#test2').click(function () {
console.log('page1');
});
}
});
page2.html
page2.html
<body>
<button id="test1">
<button id="test2">
</body>
page2.js
page2.js
$(document).ajaxComplete(function () {
if(currentPage == 'page2'){
$('#test1').click(function () {
console.log('page2');
});
/*$('#test2').click(function () {
console.log('page2');
});*/
}
});
i commented one button in each script to check if that button still has old script's affect.
我在每个脚本中注释了一个按钮,以检查该按钮是否仍然具有旧脚本的影响。