javascript - Require.js 和 document.write()

标签 javascript jquery html requirejs blockly

我想使用 require.js 异步加载一个 .js 文件,但我得到的是这个错误: 无法在“文档”上执行“写入”:除非显式打开,否则无法从异步加载的外部脚本写入文档。

产生此错误的行位于此文件的最底部:https://code.google.com/p/blockly/source/browse/trunk/blockly_uncompressed.js?r=1234

所以我尝试了一个解决方法:

var head = document.getElementById('head');
var myScript= document.createElement('script');
script1.innerHTML = "...";
head.appendChild(myScript);

这会产生错误:Uncaught TypeError: Cannot read property 'addDependency' of undefined(第 27 行)

我该如何解决这个问题?非常感谢。

最佳答案

您尝试加载的库被构建为使用 Google Closure Library ,它有自己的模块依赖系统。更具体地说,它正在做的是:

  1. 假设它正在同步加载(在页面加载期间运行)。
  2. 删除任何已加载的现有 GCL 对象。
  3. 安装自己的 GCL 副本(同步加载)。
  4. 为其目的配置其自行安装的 GCL 对象。

它通过使用 document.write 完成这些步骤创建<script>标签。打电话document.write当页面仍在加载时会导致写入的 HTML 附加到页面,而在页面加载完成后调用它会覆盖页面。如果异步加载脚本,则会在脚本加载和页面加载之间创建竞争条件,因此使用 document.write在这种情况下是被禁止的,你会得到你看到的错误:

Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.

使用您的解决方法,您的代码被异步加载,并且 <script>因此,库创建的标签也是异步加载的。 GCL 加载已启动,但当它立即尝试使用 GCL 的 addDependency 时函数,它失败了,因为 GCL 还没有完成加载,你会得到你看到的错误:

Uncaught TypeError: Cannot read property 'addDependency' of undefined (line: 27)

将 GCL 与 RequireJS 混合使用是可能的,但如您所见,它会很困惑。由于您必须为此库使用 GCL,因此最好只对所有内容使用 GCL。如果您做不到,以下 hack 可能会奏效:

  1. 用普通的 <script> 加载 GCL在 RequireJS 之外同步标记。
  2. 将库代码复制到异步加载的模块中。
  3. 将最后三行(document.write)替换为:window.BLOCKLY_BOOT();

关于javascript - Require.js 和 document.write(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30035644/

相关文章:

javascript - Ember 数据 find() 方法返回数组,但我需要一条记录

javascript - 放大的弹出窗口在灯箱前面显示滚动条

javascript - 计算多个数字字段的值 - Jquery

javascript - 定时器从 h1 传递到 h6

javascript - 不知道停止这个无限循环的语法

javascript - 使用 handlebars helper 生成新数组,并在 html 中使用新数组

html - CSS中的居中下拉菜单

html - 响应式缩放绝对定位的元素

javascript - Ember.js - 将 maxBinding 添加到 Ember.TextField