Javascript 什么是 document.write 的替代品?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4537963/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 12:49:52  来源:igfitidea点击:

What are alternatives to document.write?

javascriptdocument.write

提问by DarkLightA

In tutorials I've learnt to use document.write. Now I understand that by many this is frowned upon. I've tried print(), but then it literally sends it to the printer.

在教程中,我学会了使用document.write. 现在我明白很多人不赞成这样做。我试过print(),但后来它确实将它发送到打印机。

So what are alternatives I should use, and why shouldn't I use document.write? Both w3schools and MDN use document.write.

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

采纳答案by Darin Dimitrov

As a recommended alternative to document.writeyou could use DOM manipulationto directly query and add node elements to the DOM.

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

回答by Drazzah

The reason that your HTML is replaced is because of an evil JavaScript function: document.write().

你的 HTML 被替换的原因是一个邪恶的 JavaScript 函数:document.write().

It is most definitely "bad form." It only works with webpages if you use it on the page load; and if you use it during runtime, it will replace your entire document with the input. And if you're applying it as strict XHTML structure it's not even valid code.

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



the problem:

问题:

document.writewrites to the document stream. Calling document.writeon a closed (or loaded) document automatically calls document.openwhich will clear the document.

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

-- quote from the MDN

--引用自 MDN

document.write()has two henchmen, document.open(), and document.close(). When the HTML document is loading, the document is "open". When the document has finished loading, the document has "closed".Using document.write()at this point will erase your entire (closed) HTML document and replace it with a new (open) document. This means your webpage has erased itself and started writing a new page - from scratch.

document.write()有两个心腹document.open(), 和document.close()。加载 HTML 文档时,文档处于“打开状态”。 当文档完成加载时,文档已“关闭”。此时使用document.write()将删除整个(关闭的)HTML 文档并将其替换为一个新的(打开的)文档。这意味着您的网页已自行删除并开始编写新页面 - 从头开始​​。

I believe document.write()causes the browser to have a performance decrease as well (correct me if I am wrong).

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



an example:

一个例子:

This example writes output to the HTML document afterthe page has loaded. Watch document.write()'s evil powers clear the entire document when you press the "exterminate" button:

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

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!



the alternatives:

替代方案:

  • .innerHTMLThis is a wonderful alternative, but this attribute has to be attached to the element where you want to put the text.
  • .innerHTML这是一个很好的选择,但是这个属性必须附加到你想要放置文本的元素上。

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

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

  • .createTextNode()is the alternative recommended by the W3C.
  • .createTextNode()W3C推荐的替代方案。

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

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

NOTE: This is known to have some performance decreases (slower than .innerHTML). I recommend using .innerHTMLinstead.

注意:已知这会导致一些性能下降(比 慢.innerHTML)。我建议.innerHTML改用。



the example with the .innerHTMLalternative:

带有.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>

回答by Adrian Kalbarczyk

Here is code that should replace document.write in-place:

这是应该就地替换 document.write 的代码:

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

回答by James M. Greene

Just dropping a note here to say that, although using document.writeis highly frowned upon due to performance concerns(synchronous DOM injection and evaluation), there is also no actual 1:1 alternativeif you are using document.writeto inject script tags on demand.

只是在这里留下一个注释说,尽管document.write由于性能问题(同步 DOM 注入和评估)而强烈反对使用,但如果您使用按需注入脚本标签,也没有实际的 1:1 替代方案document.write

There are a lot of great ways to avoid having to do this (e.g. script loaders like RequireJSthat manage your dependency chains) but they are more invasive and so are best used throughoutthe site/application.

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

回答by Wolph

The question depends on what you are actually trying to do.

问题取决于您实际尝试做什么。

Usually, instead of doing document.writeyou can use someElement.innerHTMLor better, document.createElementwith an someElement.appendChild.

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

You can also consider using a library like jQuery and using the modification functions in there: http://api.jquery.com/category/manipulation/

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

回答by Justin Summerlin

This is probably the most correct, direct replacement: insertAdjacentHTML.

这可能是最正确、最直接的替代:insertAdjacentHTML

回答by Justin Summerlin

Try to use getElementById() or getElementsByName() to access a specific element and then to use innerHTML property:

尝试使用 getElementById() 或 getElementsByName() 访问特定元素,然后使用 innerHTML 属性:

<html>
    <body>
        <div id="myDiv1"></div>
        <div id="myDiv2"></div>
    </body>

    <script type="text/javascript">
        var myDiv1 = document.getElementById("myDiv1");
        var myDiv2 = document.getElementById("myDiv2");

        myDiv1.innerHTML = "<b>Content of 1st DIV</b>";
        myDiv2.innerHTML = "<i>Content of second DIV element</i>";
    </script>
</html>

回答by Sorin

You can combine insertAdjacentHTMLmethod and document.currentScriptproperty.

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

The insertAdjacentHTML()method of the Element interface parses the specified text as HTML or XML and inserts the resulting nodes into the DOM tree at a specified position:

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

  • 'beforebegin': Before the element itself.
  • 'afterbegin': Just inside the element, before its first child.
  • 'beforeend': Just inside the element, after its last child.
  • 'afterend': After the element itself.
  • 'beforebegin':在元素本身之前。
  • 'afterbegin':就在元素内部,在它的第一个子元素之前。
  • 'beforeend':就在元素内部,在它的最后一个子元素之后。
  • 'afterend':在元素本身之后。

The Document.currentScriptproperty returns the <script>element whose script is currently being processed. Best position will be beforebegin- new HTML will be inserted before <script>itself.

Document.currentScript属性返回<script>当前正在处理其脚本的元素。最佳位置将是beforebegin- 新的 HTML 将在<script>其自身之前插入。

<script>
  document.currentScript.insertAdjacentHTML(
    'beforebegin', 
    'this is the document.write alternative'
);
</script>

回答by bebopalooblog

I fail to see the problem with document.write. If you are using it before the onloadevent fires, as you presumably are, to build elements from structured data for instance, it is the appropriate tool to use. There is no performance advantage to using insertAdjacentHTMLor explicitly adding nodes to the DOM after it has been built. I just tested it three different ways with an old script I once used to schedule incoming modem calls for a 24/7 service on a bank of 4 modems.

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

By the time it is finished this script creates over 3000 DOM nodes, mostly table cells. On a 7 year old PC running Firefox on Vista, this little exercise takes less than 2 seconds using document.writefrom a local 12kb source file and three 1px GIFs which are re-used about 2000 times. The page just pops into existence fully formed, ready to handle events.

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

Using insertAdjacentHTMLis not a direct substitute as the browser closes tags which the script requires remain open, and takes twice as longto ultimately create a mangled page. Writing all the pieces to a string and then passing it to insertAdjacentHTMLtakes even longer, but at least you get the page as designed. Other options (like manually re-building the DOM one node at a time) are so ridiculous that I'm not even going there.

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

Sometimes document.writeis the thing to use. The fact that it is one of the oldest methods in JavaScript is not a point against it, but a point in its favor - it is highly optimized code which does exactly what it was intended to do and has been doing since its inception.

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

It's nice to know that there are alternative post-load methods available, but it must be understood that these are intended for a different purpose entirely; namely modifying the DOM after it has been created and memory allocated to it. It is inherently more resource-intensive to use these methods if your script is intended to write the HTML from which the browser creates the DOM in the first place.

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

Just write it and let the browser and interpreter do the work. That's what they are there for.

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

PS: I just tested using an onloadparam in the bodytag and even at this point the document is still openand document.write()functions as intended. Also, there is no perceivable performance difference between the various methods in the latest version of Firefox. Of course there is a ton of caching probably going on somewhere in the hardware/software stack, but that's the point really - let the machine do the work. It may make a difference on a cheap smartphone though. Cheers!

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

回答by Mlee

I'm not sure if this will work exactly, but I thought of

我不确定这是否完全有效,但我想到了

var docwrite = function(doc) {               
    document.write(doc);          
};

This solved the problem with the error messages for me.

这为我解决了错误消息的问题。