我可以将 javascript 动态添加到现有脚本元素吗

问题描述 投票:0回答:4

我想动态地将 javascript 添加到现有脚本元素中,例如:

var se = document.createElement('script');
se.setAttribute('type', 'text/javascript');
se.innerHTML = 'alert(1)';
document.getElementsByTagName('head').item(0).appendChild(se);

有趣的部分是

se.innerHTML = 'alert(1)';
,它是否有效?如果不是,我怎样才能以正确的方式做到这一点?

javascript html dom
4个回答
25
投票

所有浏览器当前都支持 javascript text 属性,并且当新的脚本元素(没有 src 属性)添加到文档时将评估文本。

innerHTML 或向脚本元素添加子节点不会在所有浏览器中评估脚本。

function addCode(code){
    var JS= document.createElement('script');
    JS.text= code;
    document.body.appendChild(JS);
}

//测试用例

var s= 'document.body.ondblclick=function(e){\n'+
'e=window.event? event.srcElement:e.target;\n'+
'alert(e.id || e.tagName);\n'+
'}\nalert("ready to double click!");';

addCode(s);

11
投票

这不是将 JavaScript 添加到现有脚本元素,而是创建一个新的脚本元素并将其添加到文档中。

这在现代浏览器中确实有效,但通常不会这样做,除非您确实需要在全局上下文中执行的变量中有一些代码(因此您不能从内部使用

new Function()
eval
一个函数)。

有什么用例?您真的必须这样做吗?

如果您确实尝试通过写入文档中已有的

<script>
的文本内容来更改脚本内容,则不会导致新脚本内容运行,而只会更改 DOM 的内容。当操作
<script>
元素时导致运行新脚本的具体情况因浏览器而异(尽管 HTML5 正在尝试 对其进行标准化);目前,除了简单地创建和附加新脚本之外,最好避免执行任何操作。 (如果可能的话,最好完全避免编写脚本
<script>
。)

设置

innerHTML
就可以了;不过 RoToRa 的
createTextNode
方法更好。对于老式 HTML 文档中的
<script>
innerHTML
实际上会执行与
createTextNode
相同的操作,因为
<script>
是不能包含标记的 CDATA 元素。不过,这对于 XHTML-served-as-XML 来说很重要,一般来说,当您只想设置纯文本时,避免
innerHTML
及其转义问题会更干净。

此外,您可以使用

[0]
代替
item(0)
(这被定义为 JavaScript DOM 绑定的一部分),并且通常应该避免
getAttribute
/
setAttribute
;使用像
se.type=...
这样的 DOM HTML 属性,这些属性在 IE 中更具可读性并且错误更少(尽管 IE 错误不会影响您的
type
属性)。


4
投票

如果文本包含任何可以解释为 HTML 的内容(例如

innerHTML
),则使用
<
将会中断。最好附加一个(或多个)文本节点:

var se = document.createElement('script');
se.setAttribute('type', 'text/javascript');
se.appendChild(document.createTextNode('alert(1)'));
document.getElementsByTagName('head').item(0).appendChild(se);

0
投票

如果您需要脚本标记体验,您可以将 javascript 文本转换为 Blob,然后将脚本标记的 src 属性设置为 Blob url。

© www.soinside.com 2019 - 2024. All rights reserved.