10

如何在脚本元素被执行之前删除它们

我考虑过使用 DOMNodeInserted 事件,但显然它没有捕获脚本元素。我也尝试过像这样使用 jQuery livequery 插件:

$("script").livequery(function () { 
    $(this).remove();
});

它确实删除了脚本元素,但在它被执行之后。

我正在寻找一个跨浏览器的解决方案,但我什至不确定这是否可能。我读到了Mutation Observers似乎足够接近,但我不确定它是否能解决我的问题。

如果有一种方法可以在执行之前修改脚本内容而不删除和重新创建它,那就更好了。

4

2 回答 2

17

删除脚本元素不会做任何事情。如果你能以某种方式访问​​一个脚本元素,它是很久以前执行的,删除它不会有任何效果。

所以我们需要解决它。如果您的脚本元素位于页面顶部,如下所示:

<head>
    <script src="yourscript.js"></script>

您可以向同一页面发出同步 ajax 请求,因此您可以将其内容解析为新文档,修改所有脚本标签,然后将当前文档替换为修改后的文档。

var xhr = new XMLHttpRequest,
    content,
    doc,
    scripts;

xhr.open( "GET", document.URL, false );
xhr.send(null);
content = xhr.responseText;

doc = document.implementation.createHTMLDocument(""+(document.title || ""));

doc.open();
doc.write(content);
doc.close();


scripts = doc.getElementsByTagName("script");
//Modify scripts as you please
[].forEach.call( scripts, function( script ) {
    script.removeAttribute("src");
    script.innerHTML = 'alert("hello world");';
});

//Doing this will activate all the modified scripts and the "old page" will be gone as the document is replaced
document.replaceChild( document.importNode(doc.documentElement, true), document.documentElement);

不幸的是,这不能在 jsfiddle 或 jsbin 中设置。但是您应该能够将这段代码完全复制粘贴到谷歌浏览器中此页面的控制台中。您应该会看到警报,并且当您检查 live dom 时,每个脚本都被修改了。

不同之处在于我们是在页面上执行脚本之后运行它,所以旧脚本应该仍然在页面上具有工作效果。这就是为什么要让它工作,你需要成为页面上的第一个脚本来执行它。

经测试可在谷歌浏览器中使用。doc.write由于某种原因,Firefox 完全忽略了这个调用。

于 2012-07-20T10:42:44.020 回答
-3

我不知道你想做什么。但是最好根据请求加载它们,而不是在某些条件下删除它们。

$.getScript('helloworld.js', function() {
     $("#content").html('
          Javascript is loaded successful! 
     ');
  });

如果您想在执行之前删除脚本,这是不可能的。但是你可以做的是,在一个条件下以编程方式删除脚本,如果有内存泄漏问题,那么你可以在删除脚本之前调用下面的代码。

var var1 = 'hello';
var cleanAll = function () {
    delete window.var1;
    delete window.cleanAll;
};

// unload all resources
cleanAll();
于 2012-07-17T18:27:47.797 回答