【问题标题】:async loading javascript with document.write使用 document.write 异步加载 javascript
【发布时间】:2012-10-11 19:16:32
【问题描述】:

我正在尝试异步 google map api javascript。

所以,正常的脚本标签可以工作<script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>

但是,下面的异步版本没有。

(function () {
    var gmap = document.createElement('script'); gmap.type = 'text/javascript'; gmap.async = true;
    gmap.src = 'https://maps.googleapis.com/maps/api/js?sensor=false';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(gmap, s);
})();

经过一些断点+检查操作后,我发现这条线在异步模式下运行不正常。

document.write('<' + 'script src="' + src + '"' + 
' type="text/javascript"><' + '/script>');

同步模式下的文档对象是“HTMLDocument”,但异步模式下是“#document”。加载页面后,文档对象发生了一些事情。想法?

干杯。

更新:这个问题更多是关于为什么 document.write 没有被触发,而不是异步加载谷歌地图 api。如果你在这一行设置断点,你可以看到 document.write 函数存在。这是否与 document.write 是原生的事实有关?

【问题讨论】:

    标签: javascript google-maps-api-3 asynchronous


    【解决方案1】:

    document.write 不能从异步脚本中调用,因为它与文档分离,因此您的 JS 解析器不知道将它放在哪里。充其量,浏览器会忽略它。在最坏的情况下,它可能会覆盖当前文档的顶部(例如在文档加载完成后调用 document.write)。

    不幸的是,唯一的答案是重写脚本,这在 google api 的情况下可能不是一个可行的选择。

    【讨论】:

    • 谢谢。我在这一行做了断点并尝试自己记录。它确实找到了 write() 函数,这就是为什么它很奇怪。如果write函数是分离的,那为什么不是undefined呢?
    【解决方案2】:

    当您在脚本 URL 中使用参数 callback 时,脚本不会使用 write(),您将能够异步加载 API。

    见:https://developers.google.com/maps/documentation/javascript/tutorial?hl=en#asynch

    【讨论】:

    • 是的,我收到了回调,但我在 jquery mobile 中遇到了另一个问题,它多次加载 google map api。我不喜欢警告信息。
    • 当您不喜欢该警告时,请不要多次加载 API。
    • 它是在asp mvc 中使用jqm ajax 模式的jquery mobile。因此,加载一次 API 而不是使用 jqm 事件似乎更简洁。
    【解决方案3】:

    不要使用document.write(),原因由市场和莫勒博士解释。请改用appendChild(),就像在Google's example of async loading 中所做的那样。

    【讨论】:

    • 不再有“map-simple-async”。只有“地图简单”。所以这个答案不再有用了:(
    【解决方案4】:

    我刚刚在异步加载亚马逊广告时遇到了一个非常相似的问题。通过更改其行为(在这种情况下,$ 指的是 jQuery),我能够在我的应用程序中获得近似于这些情况的 document.write

    document.write = function(content) {
      if (document.currentScript) {
        var src = document.currentScript.src
            .replace(/\#.*$/, '')
            .replace(/\?.*$/, '')
            .replace(/^.*\/\//, '');
        setTimeout(function() {
          var script = $('script').filter(function() {
            var scriptSrc = $(this).attr('src');
            return scriptSrc && scriptSrc.indexOf(src) !== -1;
          });
          $('<div></div>')
              .addClass('doc-write')
              .html(content)
              .insertAfter(script);
        }, 0);
      } else {
        HTMLDocument.prototype.write.apply(document, arguments);
      }
    };
    

    这种方法可以改进,但它足以满足我的需求。希望你会发现它有用。

    【讨论】:

    • 刚刚投了赞成票,但现在意识到这在 IE 11 中不支持。有什么建议吗?
    • 使用 callback=somefunction 参数和初始 api 加载
    【解决方案5】:

    在这里添加评论,因为我在这个问题上遇到了一些困难。异步加载脚本时(例如通过单击按钮),请确保按照site 上的说明完全

    我第一次得到document.write 错误是在我没有给出回调值时。在给出回调之后,我得到了window.initialize 错误,因为...... duh......我的代码中没有初始化函数。我将其更改为我的函数名称(类似于 loadMap)并开始工作。

    老实说,只需从网站复制代码即可。将window.onload 替换为触发上述功能所需的任何内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-17
      • 2012-11-24
      相关资源
      最近更新 更多