在页面中动态追加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. PHP的运行机制与原理(底层) [转]

    说到php的运行机制还要先给大家介绍php的模块,PHP总共有三个模块:内核.Zend引擎.以及扩展层:PHP内核用来处理请求.文件流.错误处理等相关操作:Zend引擎(ZE)用以将源文件转换成机器语 ...

  2. 如何让电脑公司Win7系统自动关闭停止响应的程序

    在注册表编辑器窗口左侧,依次展开HKEY_CURRENT_USER\ControlPanel\Desktop,选中Desktop,在右边的窗口中选择AutoEndTasks,双击打开AutoEndTa ...

  3. Debian 7(Linux) 安装SSH使用SecureCRT连接配置

    1 Debian 安装 ssh2 首先确保你的Debian或者linux安装ssh并开启ssh服务 Debian和ubuntu的安装方法一样,只要源OK的话,可以直接安装 apt-get instal ...

  4. js校验输入字符串的字节长度

    //检查输入字符串字节长度 function fucCheckLength(strTemp) { var i,sum; sum=0; var length = strTemp.length ; for ...

  5. Spark如何使用Akka实现进程、节点通信的简明介绍

    <深入理解Spark:核心思想与源码分析>一书前言的内容请看链接<深入理解SPARK:核心思想与源码分析>一书正式出版上市 <深入理解Spark:核心思想与源码分析> ...

  6. Windows Desktop 调用 WinRT api

    <Reference Include="Windows"> <HintPath>..\..\..\..\..\..\Program Files (x86)\ ...

  7. jsp:软件包 javax.servlet 不存在

    jdk里面有javax.servlet和javax.servlet.http这两个包吗? JavaServlet程序运行还需要安装JDK以外的包吗...? why?我运行JavaServlet程序的时 ...

  8. OpenCV 学习之路(1)

    OpenCV的第一个代码: #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #i ...

  9. 《Photon》

    搭建客户端: using UnityEngine;using System.Collections;using ExitGames.Client.Photon; public class GameCl ...

  10. java jdk动态代理

    在面试的时候面试题里有一道jdk的动态代理是原理,并给一个事例直接写代码出来,现在再整理一下 jdk动态代理主要是想动态在代码中增加一些功能,不影响现有代码,实现动态代理需要做如下几个操作 1.首先必 ...