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

Fly*_*wat 355 javascript

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

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

ann*_*ata 239

一些比较严重的问题:

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

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

  • 页面加载完成后执行的DW将覆盖页面,或者写一个新页面,或者不起作用

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

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

使用安全和DOM友好的DOM操作方法要好得多

  • -1,它绝对修改DOM.其他一切都很好.虽然我理解依赖于可以防止伤害的结构和方法的冲动,但这可能是一个用洗澡水甩掉婴儿的情况. (39认同)
  • DOM是用于呈现页面的数据结构,因此是用户在页面上看到的alpha和omega.HTML!= DOM是正确的,但是对DW是否修改了DOM的问题并不重要.如果DW没有修改DOM,你就看不到屏幕 - 所有浏览器都是如此,并且只要DOM是用于呈现页面的内容,它就会一直存在. (8认同)
  • _"DW执行遇到的地方"_ - 并不总是一个缺点,实际上它可以被认为是某些事情的优势,例如,添加脚本元素(实际上我唯一使用DW的东西,甚至我认为两次). (8认同)
  • FireBug不是DOM的真实表示.Mozilla尝试将HTML解析为DOM.您可以在Firebug DOM视图中看到完全破坏的HTML. (7认同)
  • @RicardoRivaldo是的,如果在文档加载完成后调用`document.write`,它们就会这样做 (7认同)
  • @vsync - 没有插入在给定点调用的给定点,你看到区别吗? (3认同)
  • 由于XHTML不再是HTML的最新版本,现在也可以安全地触发/忽略#1点吗?例如,如果您不是在编写XHTML,为什么要担心与XHTML不兼容?由于您的JavaScript不需要与其他任何人的网站进行交互,因此您只需要自己的网站. (3认同)
  • 特别是对于Firebug,这只是对DOM本身的一种了解,它不解析HTML,或者您将无法查看未解析的DOM属性。甚至firebug-lite也可以通过检查DOM本身来工作,而不是解析原始HTML(甚至更多) (2认同)
  • 以下是将document.write与appendChild交错导致的实际安全漏洞:https://bugzilla.mozilla.org/show_bug.cgi?id = 607222 (2认同)

Pet*_*ley 121

实际上document.write,本身没有任何问题.问题是滥用它真的很容易.甚至,甚至.

对于提供分析代码的供应商(如Google Analytics)而言,它实际上是分发此类代码段的最简单方式

  1. 它使脚本保持较小
  2. 他们不必担心覆盖已经建立的onload事件或包括必要的抽象来安全地添加onload事件
  3. 它非常兼容

根据document.write我的拙见,只要你在文件加载后没有尝试使用它,就不是天生就是邪恶的.

  • 就像插入分析标签一样?毕竟,这是原始问题的一部分.并且非常兼容,我的意思是只支持document.write方法的原始浏览器. (27认同)
  • document.write对html解析器做了非常可怕的事情,并且在简单的情况下只是"非常兼容". (3认同)
  • 覆盖onload事件?什么是`addEventListener`? (2认同)

Kev*_*son 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>
Run Code Online (Sandbox Code Playgroud)

我也看到了使用json2.js JSON解析/ stringify polyfill(IE7及以下版本所需)的相同技术.

<script>window.JSON || document.write('<script src="json2.js"><\/script>')</script>
Run Code Online (Sandbox Code Playgroud)

  • 可以在这里使用,但仍然"更好"使用DOM操作功能 - 甚至谷歌也用于谷歌分析.代码段是[此处](https://support.google.com/analytics/bin/answer.py?hl=zh-CN&answer=1008080). (10认同)
  • @BMiner如果通过DOM操作插入`script`元素,是否同步加载?除非是,否则它不是替代品. (8认同)
  • @JanDvorak - 好点; 在使用DOM操作时,浏览器通常会异步加载脚本.您可以使用`onload` DOM事件来确定何时可以使用异步加载的脚本. (2认同)

Sea*_*lan 39

它可以阻止您的页面

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

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


Tra*_*er1 30

优点:

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

缺点:

  • 它将呈现引擎序列化以暂停,直到加载所述外部脚本,这可能比内部脚本花费更长的时间.
  • 它通常以这样的方式使用,即脚本放在内容中,这被认为是错误的形式.

  • 还有更多的缺点.例如,谷歌Chrome将拒绝运行`document.write`,在某些情况下会创建`<script>`标签.https://developers.google.com/web/updates/2016/08/removing-document-write (3认同)

sun*_*ung 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 ......


Vin*_*ert 7

它使用XML呈现(如XHTML页面)来分解页面.

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

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

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


ale*_*emb 6

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

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

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

  • @Peter,如果在加载文档后调用它,它会覆盖内容.我猜这是aleemb的意思. (5认同)
  • 一个澄清:document.write 在页面上插入内容,它不会覆盖它们。 (2认同)
  • 您是否建议应该在代码中手动构建单个DOM节点,而不是仅仅执行类似`div.innerHTML ="<label for ='MySelect'>选择一个</ label> <select id ='MySelect'> < option value ='foo'selected =''> foo </ option> <option value ='bar'> bar </ option> </ select>";`?这似乎会产生许多不必要且不太可读的代码.这也与John Resig和其他JS开发人员提倡的方法完全相反. (2认同)

bre*_*dan 5

脱离我的头顶:

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

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

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

  • IE是宽容的,因为它不支持XHTML.如果/当他们这样做时,document.write可能会停止工作(当然只在XHTML中). (8认同)
  • XHTML与网络无关.即使是具有严格XHTML doctype的页面在这方面实际上也不被视为XML,浏览器开发人员也不会信任页面作者**. (2认同)

Tru*_*ill 5

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

一个解析器阻塞的跨源脚本,...,通过 document.write 调用。如果设备的网络连接较差,则浏览器可能会阻止此操作。

参考: