Dan*_*rzo 272 javascript jquery
知道为什么下面的代码片段没有将脚本元素添加到DOM中吗?
var code = "<script></script>";
$("#someElement").append(code);
Run Code Online (Sandbox Code Playgroud)
Hen*_*zia 349
好消息是:
这是100%的工作.
只需在脚本标记内添加一些内容,例如alert('voila!');
.你也许想问一个正确的问题,"为什么我没有在DOM中看到它?" .
Karl Swedberg对访客在jQuery API网站上的评论做了很好的解释.我不希望重复自己的一切话,你可以直接读取出现在这里(我发现很难通过评论导航那里).
所有jQuery的插入方法都在内部使用domManip函数来清理/处理元素插入DOM之前和之后.domManip函数所做的一件事就是拉出要插入的任何脚本元素,并通过"evalScript例程"运行它们,而不是将它们注入其余的DOM片段.它单独插入脚本,对它们进行评估,然后将它们从DOM中删除.
我相信jQuery这样做的原因之一是避免在某些情况下插入脚本时Internet Explorer中可能出现的"Permission Denied"错误.如果它位于您正在插入的包含元素内,然后在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);
Run Code Online (Sandbox Code Playgroud)
在那里,就像过去不是它.并且不要忘记在DOM中或在内存中清理所有被引用但不再需要的对象以防止内存泄漏.您可以考虑使用此代码进行清理:
document.body.removechild(document.body.lastChild);
delete UnusedReferencedObjects; // replace UnusedReferencedObject with any object you created in the script you load.
Run Code Online (Sandbox Code Playgroud)
这种解决方法的缺点是您可能会意外添加重复的脚本,这很糟糕.从这里开始,您可以.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;
}
Run Code Online (Sandbox Code Playgroud)
这样,您可以添加具有调试功能的脚本,同时避免脚本双重性.这只是一个原型,您可以根据自己的需要进行扩展.我一直在使用这种方法并对此非常满意.果然我永远不会使用jQuery .append()
来添加脚本.
acr*_*man 258
我已经看到一些问题,一些浏览器在你直接执行这些更改时不尊重某些更改(我的意思是通过文本创建HTML,就像你尝试使用脚本标记一样),但是当你使用内置命令执行它们时事情变得更好.试试这个:
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
$("#someElement").append( script );
Run Code Online (Sandbox Code Playgroud)
Jam*_*mes 20
你的意思是"不工作"?
jQuery检测到您正在尝试创建SCRIPT元素,并将自动在全局上下文中运行元素的内容.你告诉我这不适合你吗? -
$('#someElement').append('<script>alert("WORKING");</script>');
Run Code Online (Sandbox Code Playgroud)
编辑:如果您在运行命令后没有看到DOM中的SCRIPT元素(例如在Firebug中),因为jQuery,就像我说的那样,将运行代码,然后将删除SCRIPT元素 - 我相信SCRIPT元素总是附加到正文...但无论如何 - 在这种情况下,放置对代码执行完全没有影响.
Dar*_*win 17
这有效:
$('body').append($("<script>alert('Hi!');<\/script>")[0]);
Run Code Online (Sandbox Code Playgroud)
看起来jQuery正在用脚本做一些聪明的事情,所以你需要附加html元素而不是jQuery对象.
小智 14
试试这可能会有所帮助:
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src","scriptAnalytics.js");
document.getElementsByTagName("head")[0].appendChild(fileref);
Run Code Online (Sandbox Code Playgroud)