在页面中动态追加html片段的时候,有时候动态添加的代码会含有<script>标签,比如用了一些模板引擎,或者你的代码有些复杂的时候。然而我们用DOM提供的innerHTML方式来添加代码的时候,<script>标签中的代码并不能执行,如果有src属性,指向的外联文件也不会被加载,这并不是浏览器的bug,因为w3c文档就是这么规定的。

     那我们有什么办法可以恢复追加的<script>标签的代码执行能力呢?
 
重新构造<script>标签
     这个思路其实非常简单,用innerHTML添加的<script>无法执行,但是我们script创建节点,并用appendChild追加上去是可以的,所以我们只需要做一下二次工作就可以了,看下面的例子:
     页面上有个容器:
<div id="cont"></div>
  js代码如下:
var html = '<div>html</div><script>alert(1);<\/script>';
var cont = document.getElementById('cont');
cont.innerHTML = html;
var oldScript = cont.getElementsByTagName('script')[0];
cont.removeChild(oldScript);
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.innerHTML = oldScript.innerHTML;
cont.appendChild(newScript);
  这只是内联<script>的方法,如果是引用的外部js文件,那么我们需要为新创建的script节点指定src属性。
 
eval大法
     虽然eval因为其安全性不推荐使用,但是在此特殊场景,使用eval确是非常简单的解决方案,就是把<script>标签中的代码eval一下手动执行,就ok了,看下面代码:
var html = '<div>html</div><script>alert(1);<\/script>';
var cont = document.getElementById('cont');
cont.innerHTML = html;
var oldScript = cont.getElementsByTagName('script')[0];
cont.removeChild(oldScript);
var scriptText = oldScript.innerHTML;
eval(scriptText);
  对于内联的代码,简单而有效,如果是外部js文件,那么还是使用上面的方法,为新创建的script节点指定src属性。
 
document.write大法
     此方法可以在页面上直接输出任何html内容,包含<script>标签的话会立即执行,所以也是一种方案,如下:
var html = '<div>html</div><script>alert(1);<\/script>';
document.write(html);
  代码就直接执行了。但是他的缺点是如果代码写在文档底部,输出的内容会把页面上的其他内容全部覆盖,相当于清空了页面。解决的办法只有这样了:
<div id="cont"><script type="text/javascript">document.write(html);</script></div>
  直接把它放在标签中,就会往这个标签中输出东西了。
 
使用jQuery的html()
     上面的方法说来说去,都不如jQuery简单,因为jQuery的html()方法内部已经做了处理,如果参数中含有<script>标签,内部会使用eval和创建新节点的方式进行处理,如果是外联的js文件,jQuery会发一个同步的ajax请求来获取代码,注意,是同步的!所以不论是内联的js代码还是外联的js文件,都可以正常执行,同时在执行完后删去<script>标签。所以,使用jQuery你只需要这样:
var html = '<div>html</div><script>alert(1);<\/script>';
$('#cont').html(html);
  这个alert就妥妥的执行了。到这里,我真想说:jQuery,你真是俺亲娘!

页面动态加入<script>标签并执行代码的更多相关文章

  1. JavaScript动态创建script标签并执行js代码

    <script> //创建一个script标签 function loadScriptString(code) { var script = document.createElement( ...

  2. javascript动态创建script标签,加载完成后调用回调

    代码如下: var head = document.getElementsByTagName('head')[0]; var script = document.createElement('scri ...

  3. java动态编译 (java在线执行代码后端实现原理)(二)

    在上一篇java动态编译 (java在线执行代码后端实现原理(一))文章中实现了 字符串编译成字节码,然后通过反射来运行代码的demo.这一篇文章提供一个如何防止死循环的代码占用cpu的问题. 思路: ...

  4. java动态编译 (java在线执行代码后端实现原理)

    需求:要实现一个web网页中输入java代码,然后能知道编译结果以及执行结果 类似于菜鸟java在线工具的效果:https://c.runoob.com/compile/10 刚开始从什么概念都没有到 ...

  5. 关于html中的 script标签中的 代码写法有效性? easyui tabs的href不能载入内容页面

    script标签, 即 html中的 js脚本区域中: 它其实就是一个 普通的 html标签, 在 html 渲染器 parser 看来, 它跟其他任何的普通 的 html标签 , 比如 p 标签, ...

  6. js兼容性 - 动态删除script标签后 ,定义的函数是否执行

    hello.js function hello(){ alert('hello'); } hello.html <!DOCTYPE html> <html lang="en ...

  7. JS在当前页面插入<script>标签,并执行

    将<script>标签绑定到<html>上, html可换成body,header等其他存在的标签. var htmm =document.getElementsByTagNa ...

  8. <script>标签的加载解析执行

    转自原文 <script>标签的加载解析执行 看了很多网上的文章,都是大同小异.总结一下.内部原理还没有搞清楚,有机会再学习. 一.<script>标签的加载解析执行顺序 ht ...

  9. 如何将 JavaScript 代码添加到网页中,以及 <script> 标签的属性

    Hello, world! 本教程的这一部分内容是关于 JavaScript 语言本身的. 但是,我们需要一个工作环境来运行我们的脚本,由于本教程是在线的,所以浏览器是一个不错的选择.我们会尽可能少地 ...

随机推荐

  1. vs2015 command prompt here

    网上搜的很多方法都不能用,比如:http://app.paraesthesia.com/CommandPromptHere/ 主要是都搞错了注册表路径,写成了: HKCR,Directory\Shel ...

  2. windows平台升级ORACLE11.2.0.1到11.2.0.4

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://4445027.blog.51cto.com/4435027/1674217 一  ...

  3. ESM335x Linux输出脉冲计数

    1.综述   ESM335X具有4路PWM输出,其中PWM1和PWM2除了可以用于产生标准的PWM信号,现已支持输出脉冲计数功能,可以在应用程序中设置脉冲个 数,当输出脉冲个数达到指定值时,驱动程序自 ...

  4. tomcat 内存问题 xms xmx permsize maxPermsize

    转自:http://www.cnblogs.com/koik/p/4452029.html tomcat -Xms -Xmx -XX:PermSize -XX:MaxPermSize     在做ja ...

  5. 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)'

    error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Tra ...

  6. 流媒体协议介绍(rtp/rtcp/rtsp/rtmp/mms/hls)

    RTP           参考文档 RFC3550/RFC3551 Real-time Transport Protocol)是用于Internet上针对多媒体数据流的一种传输层协议.RTP协议详细 ...

  7. http状态码全解

    1**(信息类):表示接收到请求并且继续处理 100--客户必须继续发出请求 101--客户要求服务器根据请求转换HTTP协议版本 2**(响应成功):表示动作被成功接收.理解和接受 200--表明该 ...

  8. 谷歌CEO发布年度公开信:专注人工智能等6大业务领域

  9. MVC4相关Razor语法浅谈

    1._LayOut.cshtml 文件为mvc的布局文件,里面包函的是htm的静态文件,作为mvc其他view的基础母版使用,子视图要不想想调用它只需在页面设置@{Layout=null;}即可,现对 ...

  10. Windows下Spark单机环境配置

    1. 环境配置 a)  java环境配置: JDK版本为1.7,64位: 环境变量配置如下: JAVA_HOME为JDK安装路径,例如D:\software\workSoftware\JAVA 在pa ...