UDN-企业互联网技术人气社区

板块导航

浏览  : 850
回复  : 7

[原生js] 在 DOM 中动态插入并执行脚本

[复制链接]
芭芭拉的头像 楼主
发表于 2017-2-8 14:59:28 | 显示全部楼层 |阅读模式
  在 HTML 中脚本以 <script> 来标记,通过设置其内容或 src 属性执行内联脚本或外部脚本。 本文讨论动态地插入脚本标签时浏览器对它的解析、下载和执行行为。 动态插入脚本的场景可能包括使用 AJAX 获取脚本并动态执行(多用于性能优化), 以及运行时决定执行页面模板中的某段脚本(多用于单页异步)。

  动态执行脚本还有其他方式,比如 eval 和 new Function ,这些不在本文的讨论范围。

  执行内联脚本

  为了插入内联脚本,可以创建一个 script 元素并设置其内容,插入到 DOM 即可立即执行。 例如:
  1. var script = document.createElement('script');
  2. script.text = 'console.log("foo")';
  3. document.body.appendChild(script);
复制代码

  以下写法是等价的
  1. script.text = 'console.log("foo")';
  2. script.innerText = 'console.log("foo")';
  3. script.innerHTML = 'console.log("foo")';
复制代码

  需要注意的是内联脚本是否能够执行仍然受制于 CSP策略指令 , 该策略是由 Content-Security-Policy 响应头( rfc7762 )控制的。 例如下列设置将会禁止执行 harttle.com 以外的任何内联脚本。
  1. Content-Security-Policy: script-src harttle.com;
复制代码

  执行外部脚本

  插入并执行外部脚本的方法与内联脚本类似,只需设置 script.src 属性并插入到 DOM。 例如:
  1. var script = document.createElement('script');
  2. script.src = 'foo.js';
  3. document.body.appendChild(script);
复制代码

  与内联脚本不同的是,外部脚本的插入是异步的不会阻塞 DOM 解析。 详见 异步渲染的下载和阻塞行为 一文。

  此外有一个细节可能需要注意:一旦设置了 src 属性, <script> 标签本身的所有内容就不会再被执行了。

  innerHTML

  innerHTML 属性可用来设置 DOM 内容,但不可用来插入并执行 <script> 。 下面的内联脚本和外部脚本都不会被执行:
  1. document.body.innerHTML = '<script src="foo.js"></script>'
  2. document.body.innerHTML = '<script>console.log("foo")</script>'
复制代码

  在设置 innerHTML 时,浏览器会初始化一个新的 HTML Parser 来解析它。 只要与该 Parser 关联的 DOM 启用了 JavaScript(通常是启用的),脚本的 scripting flag 就为真, 但是即便如此, HTML 片段的解析过程中,脚本是不会执行的 。

  Create a new HTML parser, and associate it with the just created Document node. – 12.4 Parsing HTML fragments , WHATWG

  The scripting flag can be enabled even when the parser was originally created for the HTML fragment parsing algorithm, even though script elements don’t execute in that case. – 12.2.3.5 Other parsing state flags , WHATWG

  事实上,设置 innerHTML 和 outerHTML 都不执行脚本,但 document.write() 是会同步执行的。

  When inserted using the document.write() method, script elements execute (typically blocking further script execution or HTML parsing), but when inserted using innerHTML and outerHTML attributes, they do not execute at all. – 4.12.1 The script element WHATWG

  jQuery DOM Eval

  我们知道使用 jQuery html() 方法时插入的脚本总是执行的,jQuery 会检查传入的内容,并执行其中的每一个脚本。 源码在 src/core/DOMEval.js :
  1. function DOMEval( code, doc ) {
  2.     doc = doc || document;
  3.     var script = doc.createElement( "script" );
  4.     script.text = code;
  5.     doc.head.appendChild( script ).parentNode.removeChild( script );
  6. }
复制代码

相关帖子

发表于 2017-2-8 14:59:57 | 显示全部楼层
个人觉得js是一种解释性语言,它提供了一个非常方便的开发过程,不需要编译,js与HTML标识结合在一起,从而方便用户的使用操作。
使用道具 举报

回复

发表于 2017-2-14 21:48:30 | 显示全部楼层
占坑编辑ing
使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部