document.write
。现在我明白了,很多人不赞成这样做。我尝试过print()
,但它直接发送到打印机。那么,我应该使用哪些替代方法?为什么不应该使用document.write
?w3schools和MDN都使用document.write
。
document.write
。现在我明白了,很多人不赞成这样做。我尝试过print()
,但它直接发送到打印机。那么,我应该使用哪些替代方法?为什么不应该使用document.write
?w3schools和MDN都使用document.write
。
document.write()
。这绝对是“不合适”的。如果在页面加载时使用它,它只能与网页一起工作;如果在运行时使用它,则会用输入替换整个文档。如果你将其应用于严格的XHTML结构,则甚至不是有效的代码。
document.write
向文档流中写入内容。在已关闭(或已加载)的文档上调用document.write
会自动调用document.open
,这将清空文档。
-- 摘自MDN的引用
document.write()
有两个助手,document.open()
和document.close()
。当HTML文档加载时,文档是“打开”的。当文档加载完成时,文档“关闭”。此时使用document.write()
将会擦除整个(已关闭的)HTML文档,并用一个新的(打开的)文档替换它。这意味着您的网页已经擦除自己并开始编写一个新页面 - 从头开始。
我相信document.write()
也会导致浏览器性能下降(如果我错了,请纠正我)。
这个例子在页面加载后向HTML文档中输出内容。当你按下“exterminate”按钮时,观察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!
.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>
document.write()
可以在页面加载期间调用,而浏览器正在解析页面。一旦页面解析/加载完成,调用此函数也将调用document.open()
,它会清除页面并从头开始。我想不到任何理由不在页面加载期间使用该函数,除了与您在任何其他时间添加内容到页面的方式保持一致。文档在浏览器完成解析文档后立即关闭。 - Ian Hazzarddocument.write()
似乎仍然是 cdn local fallback 的最佳解决方案。我还没有尝试过 getElementById/innerHTML,但是 createElement/insertBefore 解决方案证明是 非同步的。 - Bob Steindocument.write()
会更慢,因为每次调用该函数时都必须清除文档,然后重新打开它。.innerHTML
不需要这样做,所以我很确定它实际上更快。我会寻找支持这一观点的来源。我相信如果在页面已经打开的情况下使用 document.write()
是很快的。 - Ian Hazzard这里是应该取代 document.write 的代码:
document.write=function(s){
var scripts = document.getElementsByTagName('script');
var lastScript = scripts[scripts.length-1];
lastScript.insertAdjacentHTML("beforebegin", s);
}
'beforebegin'
,而是应该放置在 'afterend'
,以匹配本地的 document.write
。虽然这并不重要。 - Gust van de WalinsertAdjacentHTML()
方法会将指定的文本解析为 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'
)
document.write
会有问题。如果您在 onload
事件触发之前使用它来构建结构化数据的元素,那么它就是适当的工具。使用 insertAdjacentHTML
或在构建 DOM 后显式添加节点没有性能优势。我刚刚用一种旧脚本测试了三种不同方式,该脚本曾用于安排银行的4个调制解调器提供24/7服务。
在完成此脚本时,它会创建超过3000个 DOM 节点,大部分是表格单元格。在运行 Firefox 的 Vista 操作系统上运行7年的 PC 上,从本地12kb源文件和三个重复使用约2000次的1px GIF使用 document.write
,这个小练习只需要不到2秒钟。页面完全形成,准备好处理事件。
使用 insertAdjacentHTML
不是直接替代品,因为浏览器会关闭脚本需要保持打开的标签,并且最终创建一个混乱的页面需要 两倍的时间。将所有组件写入字符串,然后将其传递给 insertAdjacentHTML
需要更长的时间,但至少可以按设计获取页面。其他选项(例如手动逐个重新构建 DOM)非常荒谬,我甚至不会去那里。
有时候使用 document.write
是必要的。它是 JavaScript 中最古老的方法之一并不是缺点,而是优点 - 它是高度优化的代码,完全做到了旨在做的事情,并且自从诞生以来一直如此。
知道有可替代的后加载方法很好,但必须理解这些方法完全用于修改已创建和分配给其内存的 DOM。如果您的脚本旨在编写 HTML,然后浏览器首先创建 DOM,则使用这些方法固有更多的资源消耗。
只需编写并让浏览器和解释器完成工作。这就是它们的存在目的。
PS:我刚刚在 body
标签中使用了一个 onload
参数,即使此时文档仍处于 open
状态,document.write()
也可以正常工作。此外,在最新版本的 Firefox 中各种方法之间没有可察觉的性能差异。当然,硬件/软件堆栈中可能正在进行大量缓存,但这实际上是重点-让机器完成工作。在廉价智能手机上可能会有所不同。干杯!
尝试使用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>
function documentWrite(newNode) {
// convert string to a fragment
if (typeof newNode === 'string') {
newNode = document.createRange().createContextualFragment(newNode);
}
var body = document.querySelector('body')
if (body) {
body.appendChild(newNode)
}
}
print()
解析为window.print()
。 - alexprint()
和PHP的print()
不同。JS会直接将页面发送到打印机,而PHP只是输出代码。 - Ian Hazzard