71

似乎有经验的 Web 开发人员document.write()在编写动态 HTML 时不赞成在 JavaScript 中使用。

为什么是这样?什么是正确的方法?

4

12 回答 12

55

document.write()仅在最初解析页面并创建 DOM 时才有效。一旦浏览器到达结束</body>标记并且 DOM 准备就绪,您就不能再使用document.write()了。

我不会说使用document.write()是正确还是不正确,这取决于您的情况。在某些情况下,您只需要document.write()完成任务。看看谷歌分析是如何被注入大多数网站的。

在 DOM 准备好之后,您有两种方法可以插入动态 HTML(假设我们要插入新的 HTML <div id="node-id"></div>):

  1. 在节点上使用 innerHTML:

    var node = document.getElementById('node-id');
    node.innerHTML('<p>some dynamic html</p>');
    
  2. 使用 DOM 方法:

    var node = document.getElementById('node-id');
    var newNode = document.createElement('p');
    newNode.appendChild(document.createTextNode('some dynamic html'));
    node.appendChild(newNode);
    

使用 DOM API 方法可能是最纯粹的处理方式,但innerHTML已被证明更快,并且在 JavaScript 库(如 jQuery)中使用。

注意:<script>必须在您的标签<body>内才能正常工作。

于 2009-10-07T19:23:42.473 回答
28

document.write()不适用于 XHTML。它在页面完成加载执行,只不过是写出一串 HTML。

由于 HTML 的实际内存表示是 DOM,因此更新给定页面的最佳方法是直接操作 DOM。

您执行此操作的方式是以编程方式创建节点,然后将它们附加到 DOM 中的现有位置。对于 [人为的] 示例,假设我有一个div元素维护ID“标题”属性,那么我可以通过这样做引入一些动态文本:

// create my text
var sHeader = document.createTextNode('Hello world!');

// create an element for the text and append it
var spanHeader = document.createElement('span');
spanHeader.appendChild(sHeader);

// grab a reference to the div header
var divHeader = document.getElementById('header');

// append the new element to the header
divHeader.appendChild(spanHeader);
于 2009-10-07T19:14:57.340 回答
9
  1. DOM 方法,如 Tom 所述。

  2. innerHTML,正如 iHunger 所提到的。

DOM 方法在设置属性和内容方面比字符串更可取。如果您发现自己在写作innerHTML= '<a href="'+path+'">'+text+'</a>',您实际上是在客户端创建了新的跨站点脚本安全漏洞,如果您花时间保护服务器端,这有点令人难过。

与 innerHTML 相比,DOM 方法传统上被描述为“慢”。但这并不是故事的全部。缓慢的是插入很多子节点:

 for (var i= 0; i<1000; i++)
     div.parentNode.insertBefore(document.createElement('div'), div);

这转化为 DOM 在其节点列表中找到正确位置以插入元素、向上移动其他子节点、插入新节点、更新指针等的大量工作。

另一方面,设置现有属性的值或文本节点的数据非常快;您只需更改一个字符串指针即可。这将比使用 innerHTML 序列化父级、更改它并重新解析它要快得多(并且不会丢失您的不可序列化数据,如事件处理程序、JS 引用和表单值)。

有一些技术可以在没有这么慢的 childNode 行走的情况下进行 DOM 操作。特别要注意cloneNode和使用的可能性DocumentFragment。但有时innerHTML 确实更快。您仍然可以通过使用 innerHTML 来编写带有属性值和文本内容的占位符的基本结构,然后使用 DOM 填充它们,从而获得两全其美的效果。这使您不必编写自己的escapehtml()函数来解决上述转义/安全问题。

于 2009-10-07T20:00:54.693 回答
9

在这种情况下,也许一个好主意是使用 jQuery。它提供了方便的功能,您可以执行以下操作:

$('div').html('<b>Test</b>');

查看http://docs.jquery.com/Attributes/html#val了解更多信息。

于 2009-10-07T21:03:17.110 回答
3

您可以改为更改页面上元素的innerHTMLor outerHTML

于 2009-10-07T19:15:12.757 回答
3

我不是特别擅长 JavaScript 或其最佳实践,但document.write()基本上innerHtml()允许你写出可能是也可能不是有效 HTML 的字符串;这只是字符。通过使用 DOM,您可以确保正确的、符合标准的 HTML 将防止您的页面因明显糟糕的 HTML 而中断。

而且,正如 Tom 提到的,JavaScript 是在页面加载后完成的;通过标准 HTML(通过 .html 文件或您的服务器所做的任何事情 [即 php])对您的页面进行初始设置可能是一种更好的做法。

于 2009-10-07T19:19:30.953 回答
3

element.InnerHtml= allmycontent: 将重写元素内的所有内容。你必须使用一个变量let allmycontent="this is what I want to print inside this element"来存储你想要在这个元素中的全部内容。如果不是每次调用此函数,元素的内容将被删除并替换为您最后一次调用它。

document.write(): 可以多次使用,每次调用的地方都会在页面上打印内容。

但请注意:document.write()方法仅对在页面创建时插入内容有用。因此,当需要编写大量数据(如产品或图像目录)时,请使用它来避免重复。

这里有一个简单的例子:你所有的侧边菜单的li都存储在一个数组“tab”中,你可以直接在html页面中创建一个带有script标签的js脚本,然后在你想要的迭代函数中使用write方法在页面上插入那些 li。

<script type="text/javascript">
document.write("<ul>");
for (var i=0; i<=tab.length; i++){
    document.write(tab[i]);
    }document.write("</ul>");
</script>`

这是因为 Js在加载过程中以线性方式解释。因此,请确保您的脚本位于 html 页面中的正确位置。您也可以使用外部 Js 文件,但同样您必须在您希望解释它的位置声明它。

出于这个原因,由于“用户交互” (例如单击或悬停),不能调用document.write来在您的页面上写入内容,因为随后 DOM 已经创建,并且 write 方法将像上面所说的那样编写一个新页面(清除实际执行堆栈并启动新堆栈和新 DOM 树)。在这种情况下使用:

element.innerHTML=("Myfullcontent");

要了解有关文档方法的更多信息:打开您的控制台:document; 然后打开:__proto__: HTMLDocumentPrototype

您将在文档对象中看到函数属性“write”。您还可以使用document.writeln在每个语句中添加一个新行。要了解有关函数/方法的更多信息,只需将其名称写入控制台,不带括号:document.write; 控制台将返回描述而不是调用它。

于 2018-06-07T09:03:25.947 回答
1

当然,最好的方法是完全避免在 JavaScript 中创建任何繁重的 HTML ?从服务器发送下来的标记应该包含它的大部分,然后您可以使用 CSS 而不是暴力删除/替换元素(如果可能的话)对其进行操作。

如果您正在做一些“聪明”的事情,例如模拟小部件系统,则这不适用。

于 2009-10-07T21:13:53.887 回答
1

使用 JavaScript 编写 html 的方法有很多。

document.write 仅在您想在页面实际加载之前写入页面时才有用。如果在页面加载后(在 onload 事件中)使用 document.write(),它将创建新页面并覆盖旧内容。它也不适用于包括 XHTML 在内的 XML。

另一方面,在创建 DOM(加载页面)之前不能使用其他方法,因为它们直接与 DOM 一起工作。

这些方法是:

  • node.innerHTML = "随便";
  • document.createElement('div'); 和 node.appendChild() 等。

在大多数情况下 node.innerHTML 更好,因为它比 DOM 函数更快。大多数情况下,它还使代码更具可读性和更小。

于 2009-10-07T19:24:57.493 回答
0

document.write 方法非常有限。您只能在页面完成加载之前使用它。您不能使用它来更新已加载页面的内容。

您可能想要的是innerHTML

于 2009-10-07T19:16:45.937 回答
0

document.write我认为您应该使用DOM JavaScript API而不是document.createElement.createTextNode.appendChild类似的。安全且几乎跨浏览器。

ihunger outerHTML不是跨浏览器,它只是 IE。

于 2009-10-07T19:31:52.957 回答
0

使用jquery,看看它是多么容易:

    var a = '<h1> this is some html </h1>';
    $("#results").html(a);

       //html
    <div id="results"> </div>
于 2017-05-20T02:06:32.237 回答