【发布时间】:2010-10-22 14:49:23
【问题描述】:
我知道document.write 被认为是不好的做法;我希望编制一份提交给第 3 方供应商的理由列表,说明他们为什么不应该在其分析代码的实现中使用 document.write。
请在下面说明您声称 document.write 是一种不良做法的原因。
【问题讨论】:
标签: javascript
我知道document.write 被认为是不好的做法;我希望编制一份提交给第 3 方供应商的理由列表,说明他们为什么不应该在其分析代码的实现中使用 document.write。
请在下面说明您声称 document.write 是一种不良做法的原因。
【问题讨论】:
标签: javascript
一些更严重的问题:
document.write(以下简称 DW)在 XHTML 中不起作用
DW 不直接修改 DOM,防止进一步操作 (试图找到证据,但最好是根据情况)
页面加载完成后执行的DW会覆盖页面,或者写一个新页面,或者不起作用
DW 在遇到的地方执行:它不能在给定的节点点注入
DW 正在有效地编写序列化文本,这在概念上不是 DOM 的工作方式,并且是一种创建错误的简单方法(.innerHTML 也有同样的问题)
最好使用安全且对 DOM 友好的 DOM manipulation methods
【讨论】:
document.write,他们会这样做
document.write 本身并没有什么问题。问题是它真的很容易被滥用。大体上,甚至。
就提供分析代码(如 Google Analytics)的供应商而言,这实际上是他们分发此类 sn-ps 的最简单方法
只要您在文档加载后不尝试使用它,在我看来,document.write 本质上并不是邪恶的。
【讨论】:
addEventListener 是干什么用的?
document.write 调用,这些调用会在满足某些条件时插入脚本。
它会屏蔽你的页面
document.write 仅在页面加载时有效;如果在页面加载完成后调用它,它将覆盖整个页面。
这实际上意味着您必须从内联脚本块中调用它 - 这将阻止浏览器处理随后的页面部分。在写块完成之前不会下载脚本和图像。
【讨论】:
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 解析/字符串化 polyfill (needed by IE7 and below) 的相同技术。
<script>window.JSON || document.write('<script src="json2.js"><\/script>')</script>
【讨论】:
script 元素,它会同步加载吗?除非是,否则它不是替代品。
onload DOM 事件来确定异步加载的脚本何时可用。
src)。否则它将“尽快”异步执行。
<script> 标签的 document.write 调用。见developers.google.com/web/updates/2016/08/…
专业版:
缺点:
【讨论】:
<script> 标签的document.write。 developers.google.com/web/updates/2016/08/…
这是我的两便士,一般来说,您不应该使用document.write 进行繁重的工作,但有一个实例绝对有用:
http://www.quirksmode.org/blog/archives/2005/06/three_javascrip_1.html
我最近在尝试创建 AJAX 滑块库时发现了这一点。我创建了两个嵌套的 div,并使用 JS 将 width/height 和 overflow: hidden 应用于外部 <div>。这样一来,在浏览器禁用 JS 的情况下,div 会浮动以容纳图库中的图像 - 一些不错的优雅降级。
问题是,和上面的文章一样,这个 JS 劫持 CSS 直到页面加载后才开始,导致加载 div 时瞬间闪烁。所以我需要在页面加载时编写一个 CSS 规则,或者包含一个工作表。
显然,这在 XHTML 中不起作用,但由于 XHTML 看起来有点像死鸭(在 IE 中呈现为标签汤),因此可能值得重新评估您对 DOCTYPE 的选择...
【讨论】:
它会覆盖页面上的内容,这是最明显的原因,但我不会称之为“坏”。
除非您使用 JavaScript 创建整个文档,否则它没有多大用处,在这种情况下,您可以从 document.write 开始。
即便如此,当您使用 document.write 时,您并没有真正利用 DOM——您只是将一团文本转储到文档中,所以我会说这是一种糟糕的形式。
【讨论】:
div.innerHTML = "<label for='MySelect'>Choose One</label><select id='MySelect'><option value='foo' selected=''>foo</option><option value='bar'>bar</option></select>"; 这样的事情?这似乎会产生很多不必要且可读性较差的代码。这也与 John Resig 和其他 JS 开发人员提倡的方法完全相反。
它使用 XML 呈现来破坏页面(如 XHTML 页面)。
最佳:一些浏览器切换回 HTML 渲染,一切正常。
很可能:某些浏览器在 XML 渲染模式下禁用了 document.write() 函数。
最糟糕的:某些浏览器在使用 document.write() 函数时会触发 XML 错误。
【讨论】:
在我的头顶:
document.write需要在页面加载或正文加载中使用。因此,如果您想在任何其他时间使用脚本来更新您的页面内容,document.write 几乎没有用。
从技术上讲,document.write 只会更新 HTML 页面而不是 XHTML/XML。 IE 似乎很宽容这个事实,但其他浏览器不会。
【讨论】:
Chrome 可能会阻止 document.write 在某些情况下插入脚本。发生这种情况时,它将在控制台中显示此警告:
一个解析器阻塞的跨域脚本,...,通过以下方式调用 文件。写。如果设备有这可能会被浏览器阻止 网络连接不佳。
【讨论】:
.write 被视为浏览器违规,因为它会停止解析器呈现页面。解析器接收到文档正在被修改的消息;因此,它会被阻塞,直到 JS 完成它的进程。只有此时解析器才会恢复。
采用这种方法的最大后果是性能下降。浏览器将需要更长的时间来加载页面内容。对加载时间的不利反应取决于写入文档的内容。如果您向 DOM 添加 <p> 标记而不是向 JavaScript 库传递一个包含 50 个引用的数组(我在工作代码中看到并导致 11 秒延迟 - 当然,这也取决于您的硬件)。
总而言之,如果你能提供帮助,最好避开这种方法。
【讨论】:
基于 Google-Chrome Dev Tools'Lighthouse Audit 所做的分析,
对于连接速度较慢的用户,通过
document.write()动态注入的外部脚本可以将页面加载延迟数十秒。
【讨论】:
document.write 是一种不好的做法的一个简单原因是,您无法想出一个找不到更好替代方案的方案。【讨论】:
document.write,有时很难避免 FUOC。
我不认为使用 document.write 是一个坏习惯。简而言之,对于没有经验的人来说,它就像一个高压。如果你用错了方法,你就会被煮熟。有许多开发人员至少使用过一次这种和其他危险的方法,但他们从未真正深入挖掘他们的失败。相反,当出现问题时,他们只是退出,并使用更安全的东西。那些对所谓的“不良做法”发表此类声明的人。
这就像格式化一个硬盘,当你只需要删除几个文件然后说“格式化驱动器是一个坏习惯”。
【讨论】:
可以将 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/
【讨论】:
document.write的缺点主要取决于这3个因素:
a) 实施
document.write() 主要用于在需要内容时将内容写入屏幕。这意味着它发生在任何地方,无论是在 JavaScript 文件中还是在 HTML 文件中的脚本标记内。由于脚本标签被放置在此类 HTML 文件中的任何位置,因此在与网页中的 HTML 交织在一起的脚本块中包含 document.write() 语句是个坏主意。
b) 渲染
设计良好的代码通常会获取任何动态生成的内容,将其存储在内存中,并在代码通过代码时不断对其进行操作,然后最终将其吐出到屏幕上。因此,重申上一节中的最后一点,就地渲染内容可能比可能依赖的其他内容渲染得更快,但它可能不适用于其他需要渲染内容以进行处理的代码。为了解决这个难题,我们需要摆脱 document.write() 并以正确的方式实现它。
c) 不可能的操作
一旦写完,就结束了。如果不利用 DOM,我们就无法回去操作它。
【讨论】:
我认为最大的问题是通过 document.write 写入的任何元素都会添加到页面元素的末尾。这很少是现代页面布局和 AJAX 所期望的效果。 (您必须记住,DOM 中的元素是临时的,脚本运行的时间可能会影响其行为)。
最好在页面上设置一个占位符元素,然后操作它的innerHTML。
【讨论】: