使用 Javascript 编写 HTML 的正确方法是什么?

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

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

162654 次浏览

document.write()不能用于 XHTML。它执行了 之后,页面已经完成了加载,除了写出一个 HTML 字符串之外什么也不做。

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

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

// 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);

您可以改变页面上元素的 innerHTMLouterHTML

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

你可能需要的是 InnerHTML

我不是特别擅长 JavaScript 或其最佳实践,但是 document.write()innerHtml()基本上允许你写出字符串,可能会,也可能不会是有效的 HTML; 它只是字符。通过使用 DOM,您可以确保使用适当的、符合标准的 HTML,从而防止页面通过普通糟糕的 HTML 而崩溃。

而且,正如 Tom 提到的,JavaScript 是在页面加载之后完成的; 通过标准 HTML (via)完成页面的初始设置可能是一种更好的做法。Html 文件或服务器执行的任何操作(比如 php)。

document.write()只能在页面最初被解析和 DOM 被创建的时候工作。一旦浏览器到达结束的 </body>标记并且 DOM 已经准备好了,您就不能再使用 document.write()了。

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

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

  1. 在节点上使用 innerHTML:

    var node = document.getElementById('node-id');
    node.innerHTML('<p>some dynamic html</p>');
    
  2. Using DOM methods:

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

Using the DOM API methods might be the purist way to do stuff, but innerHTML has been proven to be much faster and is used under the hood in JavaScript libraries such as jQuery.

Note: The <script> will have to be inside your <body> tag for this to work.

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

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

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

这些方法是:

  • InnerHTML = “无论如何”;
  • CreateElement (‘ div’)和 node.appChild ()等等。

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

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

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

  1. 如 Tom 所概述的 DOM 方法。

  2. 正如 iHunger 提到的 innerHTML。

对于设置属性和内容,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 引用和表单值)。

有一些技术可以在没有这么多儿童节点缓慢移动的情况下进行 DOM 操作。特别要注意 cloneNode和使用 DocumentFragment的可能性。但有时 innerHTML 确实更快。通过使用 innerHTML 为属性值和文本内容编写带占位符的基本结构,您仍然可以两全其美,然后使用 DOM 填充这些属性值和文本内容。这样可以避免编写自己的 escapehtml()函数来解决上面提到的转义/安全问题。

也许在这种情况下使用 jQuery 是个好主意。它提供了方便的功能,你可以这样做:

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

请看 http://docs.jquery.com/Attributes/html#val以获得更多信息。

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

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

使用 jquery,看看它有多简单:

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


//html
<div id="results"> </div>

将重写元素内的所有内容。您必须使用一个变量 let allmycontent="this is what I want to print inside this element"在该元素中存储所需的整个内容。如果不是每次都调用这个函数,那么元素的内容将被擦除并替换为最后一次调用。

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

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

这里有一个简单的例子: 所有用于备用菜单的 li 都存储在一个数组“ tab”中,你可以用 script 标签直接在 html 页面中创建一个 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 文件,但是您必须在希望解释它的位置声明它。

由于这个原因,“用户互动”不能调用 文件,写来在你的页面上写一些东西作为一个 “用户互动”的结果(如点击或悬停) ,因为这样 DOM 就已经被创建了,write 方法将会像上面说的那样,写一个新的页面(清除实际的执行堆栈并开始一个新的堆栈和一个新的 DOM 树)。在这种情况下,使用:

element.innerHTML=("Myfullcontent");

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

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