是否应该允许“脚本”标记自行删除?

时间:2010-03-21 06:08:47

标签: javascript internet-explorer dom

我们一直在我们的工作场所讨论这个问题,有些人反对这个行为。想听听你们的意见:

<html>
<body>
<div>
Test!
<script> document.body.removeChild(document.getElementsByTagName('div')[0]); </script>
</div>
</body>
</html>

上述脚本应该工作并执行它应该做的事情吗?首先,让我们看看这里发生了什么:

我有一个位于<div>元素内的javascript。这个javascript将删除正文中的子节点,该节点恰好包含脚本本身存在的div。

现在,上面的脚本在Firefox,Opera和IE8中运行良好。但是IE6和IE7发出警告说他们无法打开页面。

我们不要讨论IE应该如何处理这个问题(他们已经将其视为一个错误,因此在IE8中修复了它)。这里的要点是因为'SCRIPT'标签本身是DOM的一部分,是否允许它做这样的事情?这样的手术后是否应该存在?

编辑

如果我运行上面的代码,Firefox,Opera,IE9等不会删除'script'标记。但是,document.getElementsByTagName('script')。length返回0!

要理解我的意思,请在上面的代码中alert(document.getElementsByTagName('script').length);之前和之后添加document.body.removeChild(document.getElementsByTagName('div')[0]);

6 个答案:

答案 0 :(得分:8)

自我删除可以很方便的例子是,例如,一些long polling techniques肯定会在几分钟后使DOM变大。

JavaScript框架在日常例程中添加和删除脚本元素。

E.g。 jQuery 中的getScript()会在文档头中放置一个脚本标记,并在评估后立即将其删除。

他们这样做是为了保持DOM的清洁 - 否则标签就会不必要地堆积起来。 评估后不再需要它们。

我看到的唯一缺点就是调试 - 例如,带有Firebug的Firefox似乎丢失了这些脚本的下落,无法找到源代码行。 (截至撰写本文时。)

答案 1 :(得分:7)

如果问题是“,是否应该允许脚本标记自行删除?”我想是的。毕竟,脚本标记可以导致浏览器导航到另一个页面,在这种情况下,整个页面(包括这样的脚本标记)将从内存中删除。

答案 2 :(得分:5)

实际上你可以这样做:

var currentScript;
currentScript = document.currentScript || document.scripts[document.scripts.length - 1];
currentScript.parentNode.removeChild(currentScript);

答案 3 :(得分:2)

脚本正在从文档DOM树中删除DIV,并且恰好删除了脚本声明本身(在加载之后)。所以我认为它应该是允许的功能。

此外,脚本标记将一直存在,直到加载并解释并执行Javascript。在执行时,DIV(和SCRIPT)标记将从DOM树中删除,并且仅作为将被垃圾收集的对象存在。

修改

我认为这里的主要观点是SCRIPT标记仅创建 Javascript对象并将它们放在Javascript运行时引擎的内存中(这与DOM完全不同)。解释器读完SCRIPT标签后,不再需要它,可以丢弃(从DOM中删除)。

如果指示解释器(通过JS代码)在DOM中创建对 OTHER 对象的引用(例如,作为按钮单击的处理程序),则仍然可以访问Javascript函数。从该事件处理程序调用的任何函数也都可以访问。通过这种方式,您可以从button-&gt; handler-&gt;其他函数/变量中“遍历”调用堆栈。

答案 4 :(得分:1)

是的,这是一种有效的行为,因为脚本只删除自身的DOM表示。它不会以这种方式移除它自己。 实际上,脚本可以用完全不同的东西替换页面上自己的文本表示而不重新运行。

示例:

var s = document.createElement('script');
s.textContent = 'alert("Hello, world!");'+
                'document.currentScript.textContent="alert(1)";';
                // BTW, behavior is the same for innerHTML
document.body.appendChild(s);

但是,几乎没有正当理由让脚本自行删除或更改自己的代码,除非您想要保持DOM中的内容干净。此外,这不会隐藏任何愿意查看它的人的代码。通常这意味着你必须从其他代码中添加脚本,最好还是使用其他脚本中的document.body.removeChild(s);

答案 5 :(得分:-1)

使用JQuery(超过10.0.1)可以进行下一步:

<!-- you call first to jquery -->
<script id="autoremove">
      $(function(){
           //your operations
                //action
                //action
           //remove the script
           $("#autoremove").remove();
      });
</script>