知道为什么下面的这段代码没有将脚本元素添加到 DOM 中吗?
var code = "<script></script>";
$("#someElement").append(code);
知道为什么下面的这段代码没有将脚本元素添加到 DOM 中吗?
var code = "<script></script>";
$("#someElement").append(code);
好消息是:
它 100% 有效。
只需在脚本标签中添加一些内容,例如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()
来添加脚本。
我已经看到一些问题,当您直接执行某些更改时,某些浏览器不尊重某些更改(我的意思是从文本创建 HTML,就像您尝试使用 script 标签一样),但是当您使用内置命令执行这些更改时事情变得更好。尝试这个:
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
$("#someElement").append( script );
你是什么意思“不工作”?
jQuery 检测到您正在尝试创建 SCRIPT 元素,并将自动在全局上下文中运行该元素的内容。你是说这对你不起作用?——
$('#someElement').append('<script>alert("WORKING");</script>');
编辑:如果您在运行命令后没有在 DOM 中看到 SCRIPT 元素(例如在 Firebug 中),那是因为 jQuery,就像我说的,将运行代码然后删除 SCRIPT 元素 - 我相信 SCRIPT 元素总是附加到主体...但无论如何 - 在这种情况下,放置绝对与代码执行无关。
这有效:
$('body').append($("<script>alert('Hi!');<\/script>")[0]);
看起来 jQuery 正在用脚本做一些聪明的事情,所以你需要附加 html 元素而不是 jQuery 对象。