zoukankan      html  css  js  c++  java
  • 页面动态加入<script>标签并执行代码

    摘自https://www.cnblogs.com/lvdabao/p/4253704.html

     

      在页面中动态追加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);
  • 相关阅读:
    [WPF] 修改进度条样式实现斑马进度条
    [WPF] 继承Shape实现弧形、扇形控件
    ILRuntime 热更官网
    (转)Unity资源打包学习笔记(一)、详解AssetBundle的流程
    (转)基于python脚本,实现Unity全平台的自动打包
    (转)Unity实现c#热更新方案探究(三)
    (转)Unity实现c#热更新方案探究(二)
    (转)Unity实现c#热更新方案探究(一)
    (转)Unity C#热更新方案 ILRuntime学习笔记(一) Hello World
    中国已进入“零工经济”时代
  • 原文地址:https://www.cnblogs.com/wuchaofan1993/p/11156237.html
Copyright © 2011-2022 走看看