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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3619484/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:27:25  来源:igfitidea点击:

Can I add javascript dynamically to an existing script element

javascripthtmldom

提问by picknick

I want to dynamically add javascript to an existing script element something like:

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

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

The interesting part is se.innerHTML = 'alert(1)';and if it is valid? If not how can I do this the right way?

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

采纳答案by bobince

That's not adding JavaScript to an existing script element, it's creating a new script element and adding it to the document.

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

This does work in modern browsers, but you wouldn't normally do it unless you had some code in a variable that you really needed to execute in global context (so you couldn't use new Function(), or evalfrom inside a function).

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

What's the use case? Do you reallyhave to do this?

用例是什么?你真的必须这样做吗?

If you did try to change the script's content by writing to the text content of a <script>that was already in the document, it would not cause the new script content to be run, it would just change the contents of the DOM. The exact circumstances of what causes new script to be run when a <script>element is manipulated vary from browser to browser (though HTML5 is tryingto standardise it); for now it is better to avoid doing anything other than simply creating and appending a new script. (And even better to avoid scripting <script>at all, if possible.)

如果您确实尝试通过写入<script>文档中已经存在的文本内容来更改脚本的内容,则不会导致运行新的脚本内容,只会更改 DOM 的内容。当一个<script>元素被操纵时,导致新脚本运行的确切情况因浏览器而异(尽管 HTML5试图对其进行标准化);现在最好避免做任何事情,而不是简单地创建和附加一个新脚本。(<script>如果可能的话,最好完全避免编写脚本。)

Setting innerHTMLwill work; RoToRa's method with createTextNodeis better though. For <script>in an old-school-HTML document, innerHTMLwill actually do the same thing as createTextNode, since <script>is a CDATA element which cannot contain markup. It would matter for XHTML-served-as-XML though, and in general it is cleaner to avoid innerHTMLand its escaping problems when you just want to set plain text.

设置innerHTML会起作用;不过 RoToRa 的方法createTextNode更好。因为<script>在老式 HTML 文档中,innerHTML实际上会做与 相同的事情createTextNode,因为<script>是一个不能包含标记的 CDATA 元素。不过,这对于 XHTML-served-as-XML 来说很重要,而且一般来说,innerHTML当您只想设置纯文本时,避免它及其转义问题会更清晰。

Also, you can use [0]instead of item(0)(this is defined as part of the JavaScript DOM bindings), and you should in general avoid getAttribute/setAttribute; use the DOM HTML properties like se.type=...instead, which are more readable and less buggy in IE (though the IE bugs wouldn't affect you for the typeattribute).

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

回答by kennebec

All browsers currently support a javascript textproperty, and will evaluate the text when a new script element (without a src attribute) is added to the document.

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

innerHTML or adding child nodes to a script element do not evaluate the script in all browsers.

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

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

//test case

//测试用例

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);

回答by RoToRa

Using innerHTMLwill break if the text contains anything that can be interpreted as HTML such as <. It would be better to append one (or more) text nodes:

使用innerHTML如果文本包含任何可以被解释为HTML,例如将打破<。最好附加一个(或多个)文本节点:

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