在页面中动态追加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. 3. Builder(建造者)

    意图: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 适用性: 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时. 当构造过程必须允许被构造的对象有不同 ...

  2. DEV word文档转换为pdf文件

    引用aspose.net控件2.0. docement doc=new document(文件路径和名称); doc.save(输出路径\file.pdf);

  3. s1=s1+1与s1+=1的区别

    刚看到一面试题,题目是这样的:short s1=1;s1=s1+1;有什么错?short s1=1;s1+=1;有什么错? 初看之下就是s1=s1+1和s1+=1的区别.在开发中我们基本上是使用后一种 ...

  4. js判断字符串中是否含有指定汉语

    核心代码: function haveChinese(str,c){ if(escape(str).indexOf(escape(c))!=-1){ retrun true; } return fal ...

  5. 解决WampServer中MySQL数据库中文乱码的问题

    原文地址:http://blog.csdn.net/qq756703833/article/details/37971057 左键点击托盘区的WampServer图标,选择MySQL--my.ini, ...

  6. Extjs 表单验证后,几种错误信息展示方式

    今天要求对form表单验证,进行系统学习一下,故做了几个示例: Ext.onReady(function(){        var panel=Ext.create('Ext.form.Panel' ...

  7. maven SpringMVC easyUI项目创建

    在Eclipse中使用Maven创建SpringMVC项目,项目所需软件及工具可以在官网下载.Maven.Nexus及Eclipse集成Maven等到此配置完毕. 1.Maven创建Web项目. 打开 ...

  8. AVL-tree

    //avl.h#ifndef __AVL_H__#define __AVL_H__ typedef int KEY_TYPE; /* struct */typedef struct AVL{ KEY_ ...

  9. 猿团YTFCloud生态系统,全面服务创业者

    9月15日,YTFCloud已正式开启了内测. 创业者翘首以待的YTFCloud,虽然让部分创业者感受到了它的神奇,但对于更多暂时无法尝试的创业者来说,它依然有一层神秘的面纱. 今天小编就来带你近距离 ...

  10. Ubuntu-14.04.3下SDL2测试

    最近突然蛋痛想入门Linux,想写个跨平台的游戏,各种坑,备忘,稍微记点笔记. 主要参考这个文章 buntu14.04下C++开发SDL2应用 下载与安装 到http://www.libsdl.org ...