知道为什么下面的代码没有将script元素添加到DOM吗?
var code = "<script></script>";
$("#someElement").append(code);
知道为什么下面的代码没有将script元素添加到DOM吗?
var code = "<script></script>";
$("#someElement").append(code);
Answers:
我见过这样的问题:某些浏览器在您直接进行更改时(例如,您正在尝试使用script标记从文本中创建HTML)却不执行某些更改,而当您使用内置命令进行更改时情况变得更好。试试这个:
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
$("#someElement").append( script );
来自:jQuery的JSON
$("#someElement")[0].appendChild( script );
好消息是:
100%工作。
只需在script标签内添加一些内容,例如alert('voila!');
。您可能想问的正确问题也许是:“为什么我没有在DOM中看到它?” 。
Karl Swedberg在jQuery API网站上对访问者的评论做了很好的解释。我不希望重复自己的一切话,你可以直接读取出现在这里(我发现很难通过导航的评论那里)。
jQuery的所有插入方法都在内部使用domManip函数在将元素插入DOM之前和之后清洗/处理元素。domManip函数要做的一件事是提取将要插入的所有脚本元素,并通过“ evalScript例程”运行它们,而不是将它们与DOM片段的其余部分一起注入。它分别插入脚本,对其进行评估,然后将其从DOM中删除。
我相信jQuery这样做的原因之一是为了避免在某些情况下插入脚本时Internet Explorer中可能发生的“权限被拒绝”错误。如果它在要插入的包含元素中,然后在DOM中移动,则还避免了重复插入/评估相同的脚本(这可能会导致问题)。
接下来,我将通过使用.append()
函数添加脚本来总结什么是坏消息。
坏消息是..
您无法调试代码。
我不是在开玩笑,即使您debugger;
在要设置为断点的行之间添加关键字,您最终也只会得到对象的调用堆栈,而不会在源代码上看到断点,(更不用说关键字仅在webkit浏览器中有效,所有其他主流浏览器似乎都省略了该关键字)。
如果您完全了解代码的功能,那么这将是一个小缺点。但是,如果不这样做,最终将在debugger;
各处添加一个关键字,只是为了找出您(或我)的代码出了什么问题。无论如何,还有一种选择,别忘了javascript可以本地处理HTML DOM。
解决方法。
使用javascript(而非jQuery)操作HTML DOM
如果您不想失去调试功能,则可以使用javascript本机HTML DOM操作。考虑以下示例:
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "path/to/your/javascript.js"; // use this for linked script
script.text = "alert('voila!');" // use this for inline script
document.body.appendChild(script);
就在那里,就像过去不是。而且,不要忘记为引用的所有对象(无论是在DOM中还是在内存中)进行清理,以防止内存泄漏。您可以考虑以下代码来清理问题:
document.body.removechild(document.body.lastChild);
delete UnusedReferencedObjects; // replace UnusedReferencedObject with any object you created in the script you load.
这种解决方法的缺点是您可能不小心添加了重复的脚本,这很糟糕。在这里,您可以.append()
通过在添加之前添加对象验证并在添加脚本后立即从DOM中删除脚本来稍微模仿一下功能。考虑以下示例:
function AddScript(url, object){
if (object != null){
// add script
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "path/to/your/javascript.js";
document.body.appendChild(script);
// remove from the dom
document.body.removeChild(document.body.lastChild);
return true;
} else {
return false;
};
};
function DeleteObject(UnusedReferencedObjects) {
delete UnusedReferencedObjects;
}
这样,您可以添加具有调试功能的脚本,同时避免脚本重复。这只是一个原型,您可以根据自己的需要进行扩展。我一直在使用这种方法,对此非常满意。果然我将永远不会使用jQuery .append()
添加脚本。
$.getScript
内置在jQuery中。
试试这个可能会有所帮助:
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src","scriptAnalytics.js");
document.getElementsByTagName("head")[0].appendChild(fileref);
<script>
...
...jQuery("<script></script>")...
...
</script>
的</script>
字符串文字终止整个脚本,内,以避免其"</scr" + "ipt>"
可以用来代替。
"\x3cscript\x3e\x3c/script\x3e"
。在XHTML中,您只需要放入一个注释掉的CDATA块。
</
那是不允许的。参见stackoverflow.com/questions/236073/…–
如以下页面所述,在脚本文件中添加sourceURL很有帮助:https : //blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
您的脚本正在执行,您将无法使用document.write
它。使用警报进行测试,并避免使用document.write
。您的js文件中的语句document.write
将不会执行,其余函数将被执行。
我认为这是最好的解决方案。Google Analytics(分析)以这种方式注入。
var (function(){
var p="https:" == document.location.protocol ? "https://" : "http://";
d=document,
g=d.createElement('script'),
s=d.getElementsByTagName('script')[0];
g.type='text/javascript';
g.src=p+'url-to-your-script.js';
s.parentNode.insertBefore(g,s); })();
您不需要jQuery即可创建脚本DOM元素。可以使用香草ES6来完成,如下所示:
const script = "console.log('Did it work?')"
new Promise((resolve, reject) => {
(function(i,s,o,g,r,a,m){
a=s.createElement(o),m=s.getElementsByTagName(o)[0];
a.innerText=g;
a.onload=r;m.parentNode.insertBefore(a,m)}
)(window,document,'script',script, resolve())
}).then(() => console.log('Sure did!'))
不需要将其包装在中Promise
,但是这样做可以使您在脚本加载时解决承诺,从而有助于防止长时间运行的脚本出现竞争状况。
将脚本追加到正文:
$(document).ready(function() {
$("<script>", { src : "bootstrap.min.js", type : "text/javascript" }).appendTo("body");
});
我编写了一个npm
程序包,使您可以获取HTML字符串,包括脚本标签,并在执行脚本时将其附加到容器中
例:
import appendHtml from 'appendhtml';
const html = '<p>Hello</p><script src="some_js_file.js"></script>';
const container = document.getElementById('some-div');
await appendHtml(html, container);
// appendHtml returns a Promise, some_js_file.js is now loaded and executed (note the await)