为什么document.write被认为是“不好的做法”?

时间:2009-04-29 15:18:17

标签: javascript

我知道document.write被认为是不好的做法;我希望汇总一份提交给第三方供应商的理由清单,说明为什么他们不应该在他们的分析代码实施中使用document.write

请在下方提供您声称document.write为不良做法的理由。

17 个答案:

答案 0 :(得分:234)

一些更严重的问题:

  • document.write(以下称DW)在XHTML中不起作用

  • DW不会直接修改DOM,阻止进一步操作 (试图找到这方面的证据,但它最好是情境化的)

    < / LI>
  • 页面加载完成后执行的DW会覆盖页面,或者写一个新页面,或者不能正常工作

  • DW执行遇到的地方:它无法在给定节点处注入

  • DW正在有效地编写序列化文本,这不是DOM在概念上的工作方式,并且是一种创建错误的简单方法(.innerHTML也有同样的问题)

更好地使用安全和DOM友好DOM manipulation methods

答案 1 :(得分:121)

document.write本身并没有错。问题是滥用它真的很容易。总的来说,甚至是。

就提供分析代码的供应商(如Google Analytics)而言,实际上这是他们分发此类代码段的最简单方法

  1. 使脚本保持较小
  2. 他们不必担心覆盖已经建立的onload事件或包括必要的抽象来安全地添加onload事件
  3. 非常兼容
  4. 只要你在文档加载后没有尝试使用它,document.write本身就不是邪恶的,我的意见不明确。

答案 2 :(得分:42)

document.write的另一个合法用途来自HTML5 Boilerplate index.html示例。

<!-- Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if offline -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.6.3.min.js"><\/script>')</script>

我也看到了使用json2.js JSON解析/ stringify polyfill(needed by IE7 and below)的相同技巧。

<script>window.JSON || document.write('<script src="json2.js"><\/script>')</script>

答案 3 :(得分:38)

可以屏蔽您的信息页

document.write仅在页面加载时有效;如果在页面加载完成后调用它,它将覆盖整个页面。

这实际上意味着您必须从内联脚本块调用它 - 这将阻止浏览器处理后面页面的部分内容。在写入块完成之前,不会下载脚本和图像。

答案 4 :(得分:30)

<强>临

  • 这是从外部(到您的主机/域)脚本嵌入内联内容的最简单方法。
  • 您可以覆盖框架/ iframe中的整个内容。在更广泛地使用现代Ajax技术(1998-2002)之前,我曾经常常将这种技术用于菜单/导航部分。

<强>缺点:

  • 它将渲染引擎序列化为暂停,直到加载所述外部脚本,这可能比内部脚本花费更长的时间。
  • 它通常以这样的方式使用,即脚本放在内容中,这被视为不良格式。

答案 5 :(得分:9)

这是我的双重价值,一般来说你不应该使用document.write进行繁重的工作,但有一个例子肯定是有用的:

http://www.quirksmode.org/blog/archives/2005/06/three_javascrip_1.html

我最近发现这个尝试创建一个AJAX滑块库。我创建了两个嵌套的div,并使用JS将width / heightoverflow: hidden应用于外部<div>。这样,如果浏览器禁用了JS,div就会浮动以容纳图库中的图像 - 一些优雅的降级。

与上面的文章一样,这个JS劫持CSS并没有启动,直到页面加载,导致div加载时出现瞬间闪现。所以我需要在加载页面时编写CSS规则或包含工作表。

显然,这在XHTML中不起作用,但由于XHTML似乎是一个死胡同(并在IE中呈现为标签汤),因此可能值得重新评估您选择的DOCTYPE ......

答案 6 :(得分:7)

它使用XML呈现(如XHTML页面)来破坏页面。

最佳:某些浏览器切换回HTML呈现,一切正常。

可能:某些浏览器在XML呈现模式下禁用了document.write()函数。

最糟糕:使用document.write()函数时,某些浏览器会触发XML错误。

答案 7 :(得分:6)

它会覆盖页面上的内容,这是最明显的原因,但我不会称之为“糟糕”。

除非您使用JavaScript创建整个文档,否则它没什么用处,在这种情况下,您可以从document.write开始。

即便如此,当你使用document.write时,你并没有真正利用DOM - 你只是将一大块文本转储到文档中,所以我说它是不好的形式。

答案 8 :(得分:5)

脱离我的头顶:

  1. document.write需要在页面加载或正文加载中使用。因此,如果您想在任何其他时间使用该脚本来更新您的页面内容document.write几乎没用。

  2. 技术上document.write只会更新HTML页面而不是XHTML / XML。 IE似乎对这个事实很宽容,但其他浏览器不会。

  3. http://www.w3.org/MarkUp/2004/xhtml-faq#docwrite

答案 9 :(得分:3)

Chrome可能会阻止在某些情况下插入脚本的document.write。发生这种情况时,它将在控制台中显示此警告:

  

通过调用解析器阻塞,跨源脚本.......   文件撰写。如果设备有浏览器,浏览器可能会阻止此操作   网络连接不畅。

参考文献:

答案 10 :(得分:2)

基于Google-Chrome Dev Tools&#39; Lighthouse Audit enter image description here

答案 11 :(得分:1)

可以将document.write()(和.innerHTML)视为评估源代码字符串。这对于许多应用来说非常方便。例如,如果您从某个源获取HTML代码作为字符串,那么只需“评估”它就很方便。

在Lisp的上下文中,DOM操作就像操纵列表结构一样,例如通过执行以下操作创建列表(橙色):

(cons 'orange '())

而document.write()就像评估一个字符串,例如通过评估源代码字符串来创建列表,如下所示:

(eval-string "(cons 'orange '())")

Lisp还具有使用列表操作创建代码的非常有用的功能(比如使用“DOM样式”来创建JS解析树)。这意味着您可以使用“DOM样式”而不是“字符串样式”构建列表结构,然后运行该代码,例如像这样:

(eval '(cons 'orange '()))

如果您实现编码工具,例如简单的实时编辑器,则能够快速评估字符串非常方便,例如使用document.write()或.innerHTML。 Lisp在这个意义上是理想的,但你也可以在JS中做很酷的事情,很多人都这样做,比如http://jsbin.com/

答案 12 :(得分:1)

  • document.write是一个不好的做法的一个简单原因是你无法想出一个你找不到更好的选择的场景。
  • 另一个原因是你正在处理字符串而不是对象(它非常原始)。
  • 它只附加到文档。
  • 它没有任何美丽的例如MVC (Model-View-Controller)模式。
  • 使用ajax+jQueryangularJS呈现动态内容会更强大。

答案 13 :(得分:1)

document.write的缺点主要取决于以下三个因素:

a)实施

document.write()主要用于在需要内容后立即将内容写入屏幕。这意味着它发生在任何地方,无论是在JavaScript文件中还是在HTML文件中的脚本标记内。将脚本标记放在这样的HTML文件中的任何位置,将document.write()语句放在与网页内的HTML交织在一起的脚本块中是个坏主意。

b)渲染

设计良好的代码通常会采用任何动态生成的内容,将其存储在内存中,在它最终被吐出到屏幕之前通过代码时继续操作它。因此,为了重申上一节中的最后一点,就地呈现内容可能比其他可能依赖的内容更快地呈现,但是其他代码可能无法使用,而其他代码又需要呈现内容以进行处理。要解决这个难题,我们需要摆脱document.write()并以正确的方式实现它。

c)不可能的操纵

一旦它被写完就完成了。如果不进入DOM,我们就无法回过头来操纵它。

答案 14 :(得分:1)

违反浏览器

.write被认为是违反浏览器的,因为它会停止解析器渲染页面。解析器收到消息,该文档正在被修改;因此,它会被阻塞,直到JS完成其过程为止。仅在此时,解析器才能恢复。

性能

采用这种方法的最大结果是性能降低。浏览器将花费更长的时间来加载页面内容。对加载时间的不利反应取决于要写入文档的内容。如果您向DOM添加<p>标签,而不是将50多个引用的数组传递给JavaScript库,则不会有太大的区别(我在工作代码中已经看到这种情况,并且导致11秒延迟-当然,这也取决于您的硬件)。

总而言之,如果可以帮助,最好避免使用此方法。

有关更多信息,请参见Intervening against document.write()

答案 15 :(得分:-1)

我认为使用document.write根本不是一个坏习惯。简单来说,这对没有经验的人来说就像是高压。如果使用错误的方法,则会煮熟。有许多开发人员至少使用过一次此方法和其他危险方法,他们从未真正挖掘过自己的失败。相反,当出现问题时,他们会纾困,并使用更安全的东西。这些人就所谓的“不良做法”发表此类声明。

就像格式化硬盘一样,当您只需要删除几个文件然后说“格式化驱动器是一个坏习惯”时。

答案 16 :(得分:-3)

我认为最大的问题是通过document.write写的任何元素都会添加到页面元素的末尾。这很少是现代页面布局和AJAX的理想效果。 (你必须记住,DOM中的元素是暂时的,当脚本运行时可能会影响它的行为)。

最好在页面上设置占位符元素,然后操纵它的innerHTML。