不能附加<script>元素
任何想法为什么下面的代码片段不添加到DOM的脚本元素?
var code = "<script></script>"; $("#someElement").append(code);
我发现有些浏览器在直接执行这些更改时并不尊重某些更改(我的意思是从文本中创buildHTML,就像使用脚本标记一样),但是当使用内置命令执行这些更改时事情变好了。 尝试这个:
var script = document.createElement( 'script' ); script.type = 'text/javascript'; script.src = url; $("#someElement").append( script );
来自: JSON的jQuery
好消息是:
这是100%的工作。
只需在脚本标签内添加一些内容,如alert('voila!');
。 你可能想问的正确的问题可能是“我为什么没有在DOM中看到它?” 。
Karl Swedberg在jQuery API网站上对访问者的评论做了一个很好的解释。 我不想重复他所有的话,你可以在这里直接阅读(我发现很难浏览那里的评论) 。
所有jQuery的插入方法在内部使用一个domManip函数在插入到DOM之前和之后清理/处理元素。 domManip函数所做的一件事就是提取所有要插入的脚本元素,并通过“evalScript例程”运行它们,而不是将其注入DOM片段的其余部分。 它分别插入脚本,评估它们,然后从DOM中删除它们。
我相信,jQuery这样做的原因之一是避免在某些情况下插入脚本时,Internet Explorer中可能发生的“权限被拒绝”错误。 它还避免了重复插入/评估相同的脚本(这可能会导致问题),如果它位于要插入的包含元素中,然后围绕DOM移动。
接下来,我将通过使用.append()
函数来添加脚本来总结坏消息。
而坏消息是..
你不能debugging你的代码。
即使添加了debugger;
,我也不是在开玩笑, 关键字在你想要设置为断点的行之间,你最终只会得到对象的调用堆栈,而不会在源代码中看到断点(更不用说这个关键字只在webkit浏览器中工作,其他所有的主要浏览器似乎省略了这个关键字) 。
如果你完全理解你的代码的作用,那么这将是一个小缺陷。 但是,如果你不这样做,你最终会添加一个debugger;
关键字到处都是为了找出你的(或我的)代码有什么问题。 无论如何,还有一个select,不要忘了,JavaScript可以本地操纵HTML DOM。
解决方法。
使用JavaScript(而不是jQuery)来操作HTML DOM
如果你不想失去debugging能力,那么你可以使用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()
函数,在添加之前添加一个对象validation,并在添加之后从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; }
这样,您可以添加具有debuggingfunction的脚本,同时避免脚本重复。 这只是一个原型,你可以扩展任何你想要的。 我一直在使用这个方法,对此非常满意。 果然,我永远不会使用jQuery .append()
来添加一个脚本。
快乐的编码,
亨德拉Uzia。
可以使用jQuery函数getScript
dynamic加载JavaScript文件
$ .getScript('http://www.whatever.com/shareprice/shareprice.js',function(){ Display.sharePrice(); });
现在外部脚本将被调用,如果不能被加载,它将会优雅地降级。
你是什么意思“不工作”?
jQuery检测到你正在尝试创build一个SCRIPT元素,并会自动在全局上下文中运行该元素的内容。 你是否告诉我这不适合你? –
$('#someElement').append('<script>alert("WORKING");</script>');
编辑:如果在运行命令之后没有看到DOM中的SCRIPT元素(例如在Firebug中),就像我说的那样,将运行代码,然后删除SCRIPT元素 – 我相信SCRIPT元素总是附加到身体…但无论如何 – 放置在这种情况下绝对不影响代码执行。
这工作:
$('body').append($("<script>alert('Hi!');<\/script>")[0]);
看起来好像jQuery正在做一些聪明的脚本,所以你需要添加html元素而不是jQuery对象。
试试这可能是有帮助的:
var fileref=document.createElement('script'); fileref.setAttribute("type","text/javascript"); fileref.setAttribute("src","scriptAnalytics.js"); document.getElementsByTagName("head")[0].appendChild(fileref);
我想要做同样的事情,但要在其他框架中追加脚本标记!
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);
<script> ... ...jQuery("<script></script>")... ... </script>
string文字中的</script>
终止整个脚本,以避免可以使用"</scr" + "ipt>"
。
在脚本文件中添加sourceURL有助于在此页面中提到: https : //blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
- 在脚本文件中,添加一个sourceURL语句,如“// @ sourceURL = foo.js”
- 使用jQuery $ .getScript()加载脚本,脚本将在chrome dev工具的“sources”选项卡中可用
你的脚本正在执行,你不能使用它的document.write
。 使用警报来testing它并避免使用document.write
。 你的js文件和document.write
语句不会被执行,其余的函数将被执行。
这是我认为是最好的解决scheme。 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来创build一个Script 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"); });
另一种方法,你可以做到这一点,如果你想追加代码是使用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 );
我试过这个,工作正常。 用\x3C
replace<
符号。
// With Variable var code = "\x3Cscript>SomeCode\x3C/script>"; $("#someElement").append(code);
要么
//Without Variable $("#someElement").append("\x3Cscript>SomeCode\x3C/script>");
你可以在这里testing代码。
只需通过jQueryparsing来创build一个元素。
<div id="someElement"></div> <script> var code = "<script>alert(123);<\/script>"; $("#someElement").append($(code)); </script>
工作示例: https : //plnkr.co/edit/V2FE28Q2eBrJoJ6PUEBz