使用 Javascript 编写 HTML 的正确方法是啥?
Posted
技术标签:
【中文标题】使用 Javascript 编写 HTML 的正确方法是啥?【英文标题】:What is the correct way to write HTML using Javascript?使用 Javascript 编写 HTML 的正确方法是什么? 【发布时间】:2010-12-04 18:00:05 【问题描述】:似乎有经验的 Web 开发人员在编写动态 html 时不赞成在 javascript 中使用 document.write()
。
这是为什么? 正确的方法是什么?
【问题讨论】:
jQuery.我没有将此添加为实际答案,但我接近了。它可以正确处理 dom 操作,同时让您编写如下简单的内容: $(" textsub ").appendTo('body') ; 这是 jQuery meme 真正有意义的情况。 “我看到你正在尝试使用 JavaScript 编写 HTML。你应该完全放弃它并使用 jQuery!” jQuery 绝不是在 JavaScript 中创建 HTML 的“正确”方式。它是用 JavaScript 编写的,将使用下面答案中的一种或多种方法,缺点是作为一个通用库,它不会为您作为开发人员所拥有的每种情况做出明智的策略选择。 @Tim:它并不比给出的任何方法更“正确”或“不正确”,但它是一种完全有效的方法。没有一个答案在所有情况下都是“正确的”。您给定的“劣势”只是一个特征:当潜在收益微不足道时,我可能会或可能不会花时间分析 HTML 生产的最佳策略。根据您的选择,透明地管理这种复杂性可能是优势也可能是劣势。除非需要更优化的策略,否则可能会决定使用 jQuery。 @Adam - 有理有据。 “缺点”在编写最有效的代码方面仍然是准确的,但我认为效率的提高并不总是重要到足以超过 jQuery 方法的便利性,当且仅当 jQuery 已经被用于另一个非- 页面上的琐碎任务。这当然不值得单独使用 jQuery。 【参考方案1】:document.write()
仅在页面最初被解析并创建 DOM 时才有效。一旦浏览器到达结束 </body>
标记并且 DOM 准备就绪,您就不能再使用 document.write()
。
我不会说使用document.write()
是正确还是不正确,这取决于您的情况。在某些情况下,您只需要document.write()
即可完成任务。看看 Google 分析是如何被注入到大多数网站的。
在 DOM 准备好之后,您有两种方法可以插入动态 HTML(假设我们要在 <div id="node-id"></div>
中插入新的 HTML):
在节点上使用innerHTML:
var node = document.getElementById('node-id');
node.innerHTML('<p>some dynamic html</p>');
使用 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>
标记内才能正常工作。
【讨论】:
可以用,试试看=)。这可能不是你想做的,但你仍然可以。 一个很好的完整答案,谢谢。我现在明白 document.write() 仅在页面首次加载和创建时有用。为了事后动态更新页面,DOM 方法或 innerHTML() 是必须的。 你能证明innerHTML总是更快吗?我怀疑情况总是如此。如果您一次将一个节点添加到 DOM 中的现有节点,那么我预计 innerHTML 会更快,因为浏览器可能必须在每个阶段操作和重新渲染文档的某些部分,但是如果您创建一个新的节点树并在最后将其根节点添加到 DOM,我希望这与使用 innerHTML 一样快或更快。 @Maiku - 哈哈,真的 :) @Tim - 这是一个基准 quirksmode.org/dom/innerhtml.html 实际上,使用文档片段似乎是最快的:ejohn.org/blog/dom-documentfragmentsnode.innerHTML = '<p>some dynamic html</p>';
?至少在 android innerHTML 上的 WebView 上不是一个函数。【参考方案2】:
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);
【讨论】:
调用的时候实际执行了。如果您在页面加载后调用它,它将覆盖内容。 坚持使用 HTML,document.write
仍然是一个有用的工具。【参考方案3】:
Tom 概述的 DOM 方法。
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()
函数来解决上述转义/安全问题。
【讨论】:
【参考方案4】:也许在这种情况下使用 jQuery 是一个好主意。它提供了方便的功能,您可以执行以下操作:
$('div').html('<b>Test</b>');
查看http://docs.jquery.com/Attributes/html#val 了解更多信息。
【讨论】:
因为人们都在谈论更优雅、更快和跨浏览器的做事方式,并且必须加载 jQuery 来实现它,所以这不是答案。【参考方案5】:我不是特别擅长 JavaScript 或其最佳实践,但 document.write()
和 innerHtml()
基本上允许您写出 可能是或可能不是有效 HTML 的字符串;这只是字符。通过使用 DOM,您可以确保正确的、符合标准的 HTML,从而防止您的页面因明显糟糕的 HTML 而中断。
而且,正如 Tom 所说,JavaScript 是在页面加载后完成的;通过标准 HTML(通过 .html 文件或您的服务器所做的任何事情 [即 php])对您的页面进行初始设置可能是一种更好的做法。
【讨论】:
如果您使用 javascript 编写动态组件,您最终将使用 javascript 写入 DOM。虽然 document.write() 并不是真正可行的方法,但在大多数情况下,您可能会使用 innerHTML。由于 innerHTML 比在所有浏览器中使用 createNode/appendChild 快得多。当您必须生成大量 html/DOM 元素时,这一点非常重要。 + 这是文件,不是文件 ;)【参考方案6】:您可以改为更改页面上元素的innerHTML
或outerHTML
。
【讨论】:
最好是innerHTML,因为outerHTML没有得到广泛支持。【参考方案7】:element.InnerHtml= allmycontent
: 将重写元素内的所有内容。你必须使用一个变量let allmycontent="this is what I want to print inside this element"
来存储你想要在这个元素中的全部内容。如果不是每次调用此函数,元素的内容将被删除并替换为您最后一次调用它。
document.write()
: 可以多次使用,每次调用的地方都会在页面上打印内容。
但请注意:document.write() 方法仅可用于在页面创建时插入内容。因此,当需要编写大量数据(如产品目录或图像)时,请使用它来避免重复。
这里是一个简单的例子:你所有的侧边菜单的li都存储在一个数组“tab”中,你可以直接在html页面中创建一个带有script标签的js脚本,然后在一个要在页面上插入这些 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;
控制台将返回描述而不是调用它。
【讨论】:
【参考方案8】:用 JavaScript 编写 html 的方法有很多。
document.write 仅在您想在页面实际加载之前写入页面时才有用。如果在页面加载后(在 onload 事件中)使用 document.write(),它将创建新页面并覆盖旧内容。它也不适用于 XML,包括 XHTML。
另一方面,在创建 DOM(页面加载)之前不能使用其他方法,因为它们直接与 DOM 一起工作。
这些方法是:
node.innerHTML = "随便"; document.createElement('div');和 node.appendChild() 等。在大多数情况下 node.innerHTML 更好,因为它比 DOM 函数更快。大多数情况下,它还使代码更易读、更小。
【讨论】:
【参考方案9】:当然,最好的方法是完全避免在您的 JavaScript 中进行任何繁重的 HTML 创建?从服务器发送下来的标记应该包含大部分内容,然后您可以使用 CSS 而不是暴力删除/替换元素(如果可能的话)对其进行操作。
如果你正在做一些“聪明”的事情,比如模拟一个小部件系统,这不适用。
【讨论】:
【参考方案10】:document.write 方法非常有限。您只能在页面完成加载之前使用它。您不能使用它来更新已加载页面的内容。
你可能想要的是innerHTML。
【讨论】:
【参考方案11】:我认为您应该使用 DOM JavaScript API 而不是 document.write
,例如 document.createElement
、.createTextNode
、.appendChild
等。安全且几乎可以跨浏览器。
ihunger's outerHTML
不是跨浏览器,它只是 IE。
【讨论】:
【参考方案12】:使用 jquery,看看它是多么容易:
var a = '<h1> this is some html </h1>';
$("#results").html(a);
//html
<div id="results"> </div>
【讨论】:
以上是关于使用 Javascript 编写 HTML 的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
使用 JavaScript 添加多行 HTML 的正确方法是啥?