使用div的innerHTML创build脚本标记不起作用
这里是js代码
var wrap = document.createElement("div"); wrap.innerHTML = '<script type="text/javascript" src="'+scriptUrl+'"></script>'; var wrapscript = wrap.childNodes[0]; document.body.appendChild(wrapscript)
身体没有插入脚本元素,但js资源不加载,甚至没有http请求…
谁能告诉我为什么~~
问题与Zeptojs的$方法一致
$('<script type="text/javascript" src="'+scriptUrl+'"></script>').appendTo($("bdoy"))
它像上面的代码一样工作,并导致错误
这个是微不足道的。
正如规范所述( 8.4parsingHTML片段和8.2.3.5其他parsing状态标志 )quote:
当使用innerHTML
浏览器将
创build一个新的文档节点,并将其标记为HTML文档。
如果存在上下文元素,并且上下文元素的Document处于怪癖模式,则让Document处于怪癖模式。 否则,如果存在上下文元素,并且上下文元素的Document处于限制怪癖模式,则让Document处于限制怪癖模式。 否则,将文档保持为非怪异模式。
创build一个新的HTMLparsing器,并将其与刚刚创build的Document节点相关联。 …
和parsing里面的一个<script>
如果在parsing器创build时与分析器相关联的文档启用了脚本,则将脚本标记设置为“启用”,否则设置为“禁用”。
即使在最初为HTML片段parsingalgorithm创buildparsing器时,也可以启用脚本标记,尽pipe在这种情况下脚本元素不会执行。
所以只要你用innerHTML
注入它就不会执行。
而使用innerHTML
将会阻止创build的 <script>
元素被永久执行。
如spec( 4.3.1脚本元素 )中所述,quote:
dynamic更改src,type,charset,async和defer属性没有直接影响; 这些属性仅在以下所述的特定时间使用。
总结下面的描述 ,它只是在将<script>
注入到document
时parsingsrc
属性(不pipe其中包括使用innerHTML
时创build的临时 document
)。
所以,只要你想为脚本注入一个脚本并使其执行,就必须使用script = document.createElement('script')
。
设置其属性如src
和type
,可能是里面的内容(通过使用script.appendChild(document.createTextNode(content))
),然后将其附加到document.body
。
你可以试试这个:
var wrap = document.createElement('div'); var scr = document.createElement('script'); scr.src = scriptUrl; scr.type = 'text/javascript'; wrap.appendChild(scr); document.body.appendChild(wrap);
通过显式创build脚本标记,你告诉JS,innerHTML不是一个文本,而是一个可执行的脚本。
一个可能的解决scheme是,如果您不能控制插入机制,并且您不得不使用带有script
信标的innerHTML,则需要从“鬼”节点重buildDOM节点。
这是广告技术行业反复出现的问题,许多自动化系统都会复制任意的HTML代码(又名adservers ^^)。
在Chrome中正常工作:
var s = wrap.getElementsByTagName('script'); for (var i = 0; i < s.length ; i++) { var node=s[i], parent=node.parentElement, d = document.createElement('script'); d.async=node.async; d.src=node.src; parent.insertBefore(d,node); parent.removeChild(node); }
(你可以在JSFiddle中testing它 )