你知道为什么下面这段代码没有将脚本元素添加到DOM中吗?
var code = "<script></script>";
$("#someElement").append(code);
你知道为什么下面这段代码没有将脚本元素添加到DOM中吗?
var code = "<script></script>";
$("#someElement").append(code);
当前回答
我想做同样的事情,但附加一个脚本标签在其他框架!
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);
其他回答
将脚本追加到正文:
$(document).ready(function() {
$("<script>", { src : "bootstrap.min.js", type : "text/javascript" }).appendTo("body");
});
你说“不工作”是什么意思?
jQuery检测到您正在尝试创建一个SCRIPT元素,并将自动在全局上下文中运行元素的内容。你是说这对你没用吗?-
$('#someElement').append('<script>alert("WORKING");</script>');
编辑:如果你在运行命令后没有在DOM中看到SCRIPT元素(例如在Firebug中),这是因为jQuery,就像我说的,将运行代码,然后将删除SCRIPT元素-我相信SCRIPT元素总是附加到主体…但无论如何,在这种情况下,位置对代码执行完全没有影响。
如此:
$('body').append($("<script>alert('Hi!');<\/script>")[0]);
jQuery似乎在脚本上做了一些聪明的事情,所以你需要附加html元素而不是jQuery对象。
好消息是:
100%有效。
只需在脚本标记中添加一些内容,例如alert('voila!');。您可能想问的正确问题是,“为什么我在DOM中没有看到它?”
Karl Swedberg在jQuery API网站上对访问者的评论做了一个很好的解释。我不想重复他所有的话,你可以直接在这里阅读(我发现很难浏览那里的评论)。
All of jQuery's insertion methods use a domManip function internally to clean/process elements before and after they are inserted into the DOM. One of the things the domManip function does is pull out any script elements about to be inserted and run them through an "evalScript routine" rather than inject them with the rest of the DOM fragment. It inserts the scripts separately, evaluates them, and then removes them from the DOM. I believe that one of the reasons jQuery does this is to avoid "Permission Denied" errors that can occur in Internet Explorer when inserting scripts under certain circumstances. It also avoids repeatedly inserting/evaluating the same script (which could potentially cause problems) if it is within a containing element that you are inserting and then moving around the DOM.
接下来,我将通过使用.append()函数添加一个脚本来总结坏消息。
坏消息是…
你不能调试代码。
我不是在开玩笑,即使你添加了调试器;关键字,你将最终只得到对象的调用堆栈,而看不到源代码上的断点,(更不用说这个关键字只适用于webkit浏览器,所有其他主流浏览器似乎都省略了这个关键字)。
如果您完全理解您的代码是做什么的,那么这将是一个小缺点。但如果你不这样做,你最终会添加一个调试器;关键字到处都是,只是为了找出你(或我)的代码有什么问题。不管怎样,还有另一种选择,不要忘记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()来添加脚本。
我写了一个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)
在这里找到它:https://www.npmjs.com/package/appendhtml