document.write的替代品是什么?

Dar*_*htA 64 javascript document.write

在我学会使用的教程中document.write.现在我明白很多人对此不以为然.我试过了print(),但它确实将它发送到打印机.

那么我应该使用哪些替代品,为什么我不应该使用document.write?w3schools和MDN都使用document.write.

Dra*_*zah 76

更换HTML的原因是因为一个邪恶的JavaScript函数:document.write().

这绝对是"糟糕的形式".如果您在页面加载时使用它,它只适用于网页; 如果在运行时使用它,它将用输入替换整个文档.如果你将它作为严格的XHTML结构应用它甚至不是有效的代码.


问题:

document.write写入文档流.调用document.write已关闭(或已加载)的文档会自动调用document.open清除文档的文档.

- 来自MDN的引用

document.write()有两个心腹document.open(),和document.close().加载HTML文档时,文档是"打开"的. 文档加载完毕后,文档已"关闭".此时使用document.write()将删除整个(已关闭)HTML文档并将其替换为新的(打开)文档.这意味着您的网页已经删除,并开始从头开始编写新页面.

我相信document.write()也会导致浏览器性能下降(如果我错了,请纠正我).


一个例子:

此示例在页面加载后将输出写入HTML文档.document.write()当您按下"消灭"按钮时,手表的邪恶力量会清除整个文档:

I am an ordinary HTML page.  I am innocent, and purely for informational purposes. Please do not <input type="button" onclick="document.write('This HTML page has been succesfully exterminated.')" value="exterminate"/>
me!
Run Code Online (Sandbox Code Playgroud)


替代方案:

  • .innerHTML 这是一个很好的选择,但是必须将此属性附加到要放置文本的元素.

例: document.getElementById('output1').innerHTML = 'Some text!';

  • .createTextNode()W3C推荐的替代方案.

例: var para = document.createElement('p'); para.appendChild(document.createTextNode('Hello, '));

注意:已知这会降低性能(慢于.innerHTML).我推荐使用.innerHTML.


.innerHTML替代的例子:

I am an ordinary HTML page. 
I am innocent, and purely for informational purposes. 
Please do not 
<input type="button" onclick="document.getElementById('output1').innerHTML = 'There was an error exterminating this page. Please replace <code>.innerHTML</code> with <code>document.write()</code> to complete extermination.';" value="exterminate"/>
 me!
<p id="output1"></p>
Run Code Online (Sandbox Code Playgroud)

  • @Godisgood,document.write没有办法遇到性能问题,因为它与浏览器在加载初始HTTP响应时使用的功能完全相同. (2认同)

Adr*_*zyk 24

以下是应该替换document.write的代码:

document.write=function(s){
    var scripts = document.getElementsByTagName('script');
    var lastScript = scripts[scripts.length-1];
    lastScript.insertAdjacentHTML("beforebegin", s);
}
Run Code Online (Sandbox Code Playgroud)

  • 如果页面上没有脚本,这不会起作用吗? (2认同)

Sor*_*rin 15

您可以结合insertAdjacentHTML方法和document.currentScript属性。

insertAdjacentHTML()Element 接口的方法将指定文本解析为 HTML 或 XML,并将结果节点插入到 DOM 树的指定位置

  • 'beforebegin': 在元素本身之前。
  • 'afterbegin': 就在元素内部,在它的第一个子元素之前。
  • 'beforeend': 就在元素内部,在它的最后一个子元素之后。
  • 'afterend': 在元素本身之后。

document.currentScript属性返回<script>当前正在处理其脚本的元素。最好的位置是beforebegin —— 新的 HTML 将被插入到<script>它自己之前。为了匹配document.write的本机行为,可以文本定位在afterend,但是随后对函数的连续调用中的节点的放置顺序与您调用它们的顺序不同(就像document.write那样),而是相反。HTML 出现的顺序可能比它们相对于<script>标签的位置更重要,因此使用beforebegin

document.currentScript.insertAdjacentHTML(
  'beforebegin', 
  'This is a document.write alternative'
)
Run Code Online (Sandbox Code Playgroud)


Dar*_*rov 10

作为推荐的替代方案,document.write您可以使用DOM操作直接查询并向DOM添加节点元素.

  • 不要只是把链接. (13认同)
  • 如果它解决了*为什么*document.write有问题的问题,这将是一个更好的答案,因为[这个答案确实](http://stackoverflow.com/a/27531116/19068). (5认同)

Jam*_*ene 10

只是在这里删除一个注释,尽管document.write由于性能问题(同步DOM注入和评估)而使用非常不受欢迎,但如果您使用按需注入脚本标记,则也没有实际的1:1替代方法document.write.

有很多很好的方法可以避免不得不这样做(例如,像管理你的依赖链的RequireJS这样的脚本加载器),但它们更具侵入性,因此最好在整个站点/应用程序中使用.


Wol*_*lph 7

问题取决于你实际上要做什么.

通常,而不是做document.write你可以使用someElement.innerHTML或更好,document.createElementsomeElement.appendChild.

您还可以考虑使用类似jQuery的库并使用其中的修改函数:http://api.jquery.com/category/manipulation/


beb*_*log 6

我看不到document.write. 例如,如果您在onload事件触发之前使用它来从结构化数据构建元素,那么它是合适的工具。在insertAdjacentHTML构建 DOM 后使用或显式向 DOM 添加节点没有性能优势。我刚刚用一个旧脚本测试了它三种不同的方式,我曾经用来在一组 4 个调制解调器上为 24/7 服务安排传入的调制解调器呼叫。

当它完成时,这个脚本创建了 3000 多个 DOM 节点,主要是表格单元。在一台运行 Firefox 和 Vista 的 7 年前的 PC 上,这个小练习使用document.write本地 12kb 源文件和三个 1px GIF花费不到 2 秒,这些 GIF 被重复使用了大约 2000 次。该页面刚刚弹出并完全成形,准备好处理事件。

使用insertAdjacentHTML不是直接的替代品,因为浏览器会关闭脚本需要保持打开状态的标签,并且最终创建损坏的页面需要两倍的时间。将所有部分写入一个字符串,然后将其传递给insertAdjacentHTML需要更长的时间,但至少您得到了设计好的页面。其他选项(例如一次一个节点手动重新构建 DOM)太荒谬了,我什至不会去那里。

有时document.write是要使用的东西。它是 JavaScript 中最古老的方法之一,这一事实并不是反对它,而是支持它的一点——它是高度优化的代码,它完全按照它的意图去做,并且从一开始就一直在做。

很高兴知道有其他可用的后加载方法,但必须理解这些方法完全用于不同的目的;即在创建 DOM 并为其分配内存后修改 DOM。如果您的脚本旨在编写浏览器首先从中创建 DOM 的 HTML,那么使用这些方法本质上会占用更多资源。

只需编写它,让浏览器和解释器完成工作。这就是他们的目的。

PS:我只是使用测试onload在参数body标签,甚至在这一点上的文档仍然是opendocument.write()发挥预期的作用。此外,在最新版本的 Firefox 中,各种方法之间没有明显的性能差异。当然,硬件/软件堆栈中的某个地方可能会进行大量缓存,但这才是真正的重点 - 让机器完成工作。不过,它可能会对便宜的智能手机产生影响。干杯!


Jus*_*lin 5

这可能是最正确,直接的替代品:insertAdjacentHTML.