在文档上执行写入:除非明确打开,否则无法从异步加载的外部脚本写入文档。

IT技术 javascript asynchronous onload document.write
2021-01-25 04:02:18

我正在尝试在页面加载执行后加载某个脚本,如下所示:

function downloadJSAtOnload(){
            var element = document.createElement("script");
            element.src = "scriptSrc";
            document.body.appendChild(element);
        }

         if (window.addEventListener)
                  window.addEventListener("load", downloadJSAtOnload, false);
            else if (window.attachEvent)
                  window.attachEvent("onload", downloadJSAtOnload);
            else window.onload = downloadJSAtOnload;

虽然此脚本似乎执行并下载“scriptSrc”,并将其附加到 body 标记的末尾之前,但它会在控制台 (chrome) 中产生以下消息(不是错误)

无法在“文档”上执行“写入”:除非明确打开,否则无法从异步加载的外部脚本写入文档。

这到底是什么意思?我应该做些不同的事情吗?即使我得到了预期的行为?

3个回答

异步加载的脚本可能会在文档完全解析和关闭后运行。因此,您不能document.write()从这样的脚本中使用(技术上您可以,但它不会做您想做的事)。

您将需要document.write()通过创建 DOM 元素,然后将它们插入到特定的父元素中,使用.appendChild().insertBefore()或设置.innerHTML或某种直接 DOM 操作的机制来使用显式 DOM 操作替换该脚本中的任何语句

例如,代替内联脚本中的此类代码:

<div id="container">
<script>
document.write('<span style="color:red;">Hello</span>');
</script>
</div>

您可以使用它来替换上面动态加载的脚本中的内联脚本:

var container = document.getElementById("container");
var content = document.createElement("span");
content.style.color = "red";
content.innerHTML = "Hello";
container.appendChild(content);

或者,如果容器中没有您需要附加的其他内容,您可以简单地执行以下操作:

var container = document.getElementById("container");
container.innerHTML = '<span style="color:red;">Hello</span>';
@jfriend,Re“但它不会做你想做的事”,如果它做了怎么办?如果需要,如何启用它?(这曾经适用于较旧的浏览器。)
2021-03-20 04:02:18
@Pacerier -document.write()在文档加载完成后使用会导致当前文档被清除,然后写入进入一个新的空白文档。如果您想要这种行为,那么只需在插入内容之前清除当前的 DOM。如果您有比这更详细的问题,请提出一个新问题,展示您拥有的代码并描述所需的结果。
2021-03-27 04:02:18
但是当我声明“document.body.appendChild(element)”时,我不是在做类似的事情吗?
2021-04-06 04:02:18

聚会有点晚了,但 Krux 为此创建了一个脚本,称为Postscribe我们能够使用它来解决这个问题。

我们将 JavaScript CDN 链接提供给网站所有者以使用此标签投放广告。我们不能要求每个所有者都放置这个 postscribe.js,因此我们需要将它与我们的 JS 一起提供。
2021-03-17 04:02:18
@RockStar 您的问题有什么解决方案。即使我有同样的问题
2021-03-17 04:02:18
除非您明确使用该postscribe功能,否则 postscribe 似乎什么都不做- 非常令人失望
2021-04-01 04:02:18
用我们的 JavaScript 库传递这个库的最佳方法是什么?情况是我们将 JS 标签提供给在该网站上运行的客户端。
2021-04-07 04:02:18
我不是 100% 确定你在这里问@RockStar,但任何包含 JS 的正常方法都应该有效。您可以打开cdnjs.com/libraries/postscribe并将代码复制/粘贴到现有的 JS 文件中,或者您可以添加一个 <script> 标记指向该文件的 cdnjs 托管版本。在这种情况下,您可能需要在其他脚本之前加载它,因此如果您无法使其正常工作,这可能是原因。
2021-04-11 04:02:18

如果这对我遇到同样问题的任何人有用。我正在通过 jQuery 将页脚引入网页。在那个页脚里面是一些用于广告和重新定位的谷歌脚本。我不得不从页脚中移动这些脚本并将它们直接放在页面中,这样就消除了通知。

我遇到了同样的问题,但脚本位于标签管理器创建的包中。问题是由async属性引起的,唯一的解决方案是删除该属性,因为我不允许从我们的标签管理器中移动脚本。
2021-03-24 04:02:18