document.write的替代品是什么?

时间:2010-12-27 10:13:05

标签: javascript document.write

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

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

11 个答案:

答案 0 :(得分:68)

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

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


问题:

  

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

- quote from the 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!


替代方案:

  • .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>

答案 1 :(得分:22)

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

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

答案 2 :(得分:11)

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

答案 3 :(得分:9)

只是在这里删除一条说明,尽管由于performance concerns(同步DOM注入和评估)而使用document.write非常不受欢迎,但还有没有实际的1:1替代方案如果您使用document.write按需注入脚本标记。

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

答案 4 :(得分:7)

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

通常,您可以使用document.write或更好,someElement.innerHTML使用document.createElement而不是someElement.appendChild

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

答案 5 :(得分:5)

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

答案 6 :(得分:3)

尝试使用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>

答案 7 :(得分:2)

我没有看到document.write的问题。如果你在onload事件发生之前使用它,就像你想象的那样,例如,从结构化数据构建元素,它就是适当的工具。在构建DOM之后使用insertAdjacentHTML或明确地向DOM添加节点没有性能优势。我刚刚用一个旧脚本测试了它,它曾用于调度4个调制解调器组的24/7服务的调制解调器调用。

到完成时,此脚本会创建超过3000个DOM节点,主要是表格单元格。在Vista上运行Firefox的7岁PC上,使用来自本地12kb源文件的document.write和使用大约2000次重复使用的3个1px GIF,这个小练习只需不到2秒。页面刚刚完全形成,准备处理事件。

使用insertAdjacentHTML不能直接替代,因为浏览器会关闭脚本需要保持打开的标记,并且需要两倍来最终创建一个错位页面。将所有部分写入字符串然后将其传递给insertAdjacentHTML需要更长的时间,但至少可以按设计获得页面。其他选项(比如一次手动重建一个节点的DOM)是如此荒谬,以至于我甚至没有去那里。

有时使用document.write。事实上,它是JavaScript中最古老的方法之一并不是一个反对它的观点,而是一个有利于它的点 - 它是高度优化的代码,它完全符合它的目的,并且从一开始就一直在做。

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

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

PS:我刚刚使用onload标记中的body参数进行了测试,即使此时文档仍然是opendocument.write()也可以按预期运行。此外,最新版本的Firefox中的各种方法之间没有可察觉的性能差异。当然,硬件/软件堆栈中的某些地方可能会有大量的缓存,但这才是真正的 - 让机器完成工作。尽管如此,它可能对便宜的智能手机产生影响。干杯!

答案 8 :(得分:1)

document.currentScript.insertAdjacentHTML('beforebegin', 'this is the document.write alternative');

https://developer.mozilla.org/en-US/docs/Web/API/Document/currentScript https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML

答案 9 :(得分:0)

使用

var  documentwrite =(value, method="", display="")=>{
            switch(display) {
                case "block":
                 var x = document.createElement("p");
                  break;
                  case "inline":
                 var x = document.createElement("span");
                  break;
                default:
                 var x = document.createElement("p");
              }
            
            var t = document.createTextNode(value);
            x.appendChild(t);
            
            if(method==""){
             document.body.appendChild(x);
            }
            else{
            document.querySelector(method).appendChild(x);
           
            }
        }

并根据您的要求调用该函数,如下所示

  documentwrite("My sample text"); //print value inside body
  documentwrite("My sample text inside id", "#demoid", "block");  // print value inside id and display block
  documentwrite("My sample text inside class", ".democlass","inline"); // print value inside class and and display inline 

答案 10 :(得分:-2)

我不确定这是否能正常工作,但我想到了

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

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