知道为什么下面这段代码没有将脚本元素添加到DOM?
var code = "<script></script>";
$("#someElement").append(code);
答案 0 :(得分:347)
好消息是:
100%正常工作。
只需在脚本代码中添加内容,例如alert('voila!');
。您可能想问的正确问题, “我为什么不在DOM中看到它?” 。
Karl Swedberg对访客在jQuery API site的评论做了很好的解释。我不要想重复他所有的话,你可以直接阅读那里这里(我发现很难浏览那里的评论)
所有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()
添加脚本。
答案 1 :(得分:253)
我已经看到一些问题,某些浏览器在你直接执行这些更改时不尊重某些更改(我的意思是通过文本创建HTML,就像你尝试使用脚本标记一样),但是当你使用内置标签创建它们时-in命令事情变得更好。试试这个:
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
$("#someElement").append( script );
答案 2 :(得分:23)
$.getScript('http://www.whatever.com/shareprice/shareprice.js', function() { Display.sharePrice(); });
现在将调用外部脚本,如果无法加载,它将正常降级。
答案 3 :(得分:20)
你的意思是“不工作”?
jQuery检测到您正在尝试创建SCRIPT元素,并将自动在全局上下文中运行元素的内容。你告诉我这不适合你吗? -
$('#someElement').append('<script>alert("WORKING");</script>');
编辑:如果在运行命令后没有在DOM中看到SCRIPT元素(例如在Firebug中),因为jQuery,就像我说的那样,将运行代码,然后将删除SCRIPT元素 - 我相信SCRIPT元素总是附加到正文......但无论如何 - 在这种情况下,放置对代码执行完全没有影响。
答案 4 :(得分:17)
这有效:
$('body').append($("<script>alert('Hi!');<\/script>")[0]);
似乎jQuery正在使用脚本做一些聪明的事情,所以你需要附加html元素而不是jQuery对象。
答案 5 :(得分:14)
尝试这可能会有所帮助:
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src","scriptAnalytics.js");
document.getElementsByTagName("head")[0].appendChild(fileref);
答案 6 :(得分:3)
<script>
...
...jQuery("<script></script>")...
...
</script>
字符串文字中的</script>
会终止整个脚本,以避免使用"</scr" + "ipt>"
代替。
答案 7 :(得分:3)
我想做同样的事情,但要在其他框架中添加脚本标记!
var url = 'library.js';
var script = window.parent.frames[1].document.createElement('script' );
script.type = 'text/javascript';
script.src = url;
$('head',window.parent.frames[1].document).append(script);
答案 8 :(得分:2)
如本页所述,在脚本文件中添加sourceURL有帮助: https://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
答案 9 :(得分:1)
您的脚本正在执行,您无法使用document.write
。使用警报对其进行测试,避免使用document.write
。使用document.write
的js文件的语句将不会被执行,其余的函数将被执行。
答案 10 :(得分:1)
这是我认为最好的解决方案。 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); })();
答案 11 :(得分:1)
您不需要jQuery来创建Script DOM Element。它可以像香草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
中,但这样做可以让您在脚本加载时解析承诺,从而有助于防止长时间运行脚本的竞争条件。
答案 12 :(得分:0)
将脚本附加到正文:
$(document).ready(function() {
$("<script>", { src : "bootstrap.min.js", type : "text/javascript" }).appendTo("body");
});
答案 13 :(得分:0)
如果要添加代码,另一种方法是使用document.createElement
方法,然后使用.innerHTML
代替.src
。
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.innerHTML = 'alert("Hey there... you just appended this script to the body");';
$("body").append( script );
答案 14 :(得分:0)
我试过这个one并且运行正常。只需将<
符号替换为\x3C
即可。
// With Variable
var code = "\x3Cscript>SomeCode\x3C/script>";
$("#someElement").append(code);
或
//Without Variable
$("#someElement").append("\x3Cscript>SomeCode\x3C/script>");
您可以测试代码here。
答案 15 :(得分:0)
可以尝试这样
var code = "<script></" + "script>";
$("#someElement").append(code);
你不能做"<script></script>"
的唯一原因是因为javascript中不允许使用字符串,因为DOM层无法解析js和HTML的内容。
答案 16 :(得分:0)
我写了一个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)
答案 17 :(得分:-1)
只需使用jQuery解析它就可以创建一个元素。
<div id="someElement"></div>
<script>
var code = "<script>alert(123);<\/script>";
$("#someElement").append($(code));
</script>