管理和初始化表示DOM元素的JS对象的最佳方法

时间:2010-10-13 18:34:09

标签: javascript ajax oop dhtml

创建网页时,用户会动态创建和销毁内容,构建和初始化javascript功能和DOM元素的最佳方式是什么?

示例 - 假设您有一个待办事项列表,用户可以重新订购,创建和销毁项目:

  • 每个项目都有一个可视化表示(即Dom元素),需要在用户添加项目时动态创建
  • 每个项目还将具有javascript表示(即具有自定义方法和属性的javascript对象),当用户添加项目时将对其进行实例化

处理创建初始DOM元素及其javascript表示的赌注方式是什么?我可以看到几种可能性:

  • 让服务器吐出结构化的HTML并让JS通过遍历DOM来收集初始状态。
  • 让服务器吐出结构化的HTML和一些JS代码来创建对象集并将它们与DOM表示相关联。
  • 让服务器吐出JS对象,并在加载页面后动态创建DOM元素。

2 个答案:

答案 0 :(得分:2)

我不确定最好的方式;这取决于你的要求。

我最喜欢的方法是为每个数据结构设置一个JavaScript模板;这样,如果你正在进行AJAX调用,你必须通过网络发送的唯一内容是数据本身,而不是HTML。

您还可以使用混合方法,其中服务器为初始页面加载吐出结构化HTML,读取结构(您应该在HTML中具有足够的语义含义以了解您正在处理的内容,即使您不使用此方法),但仍使用JavaScript模板填充数据以进行更新。这种方法的明显缺点是,您最终会在客户端和服务器端复制模板;但是,有一些工具和框架(例如Google Closure模板)允许您编写一次模板,并为您生成适当的服务器和客户端版本。如果您希望应用程序在没有JavaScript的情况下工作,您将 从服务器发送HTML。如果您需要JavaScript,我没有理由让服务器吐出HTML,除非您担心多个HTTP请求。

是否要发送JavaScript结构和初始页面加载的HTML因此取决于几个因素:您要针对哪些CPU? (桌面,移动)您的客户将拥有哪种类型的带宽? (低于3G的速度?)如果你有无限的带宽但CPU有限,那么在首页加载时发送结构和数据会更有意义。如果您拥有无限的CPU但带宽有限,那么您只需要发送结构或数据并从中生成另一个,等等。

你也可以使用类似GWT或jQuery的小部件来处理很多这样的痛苦,但它们都是同样的想法:每个小部件/结构/无论你有什么样的HTML布局副本-want-to call-it,这样数据本身就可以保持精益,很好用。

当然,您可以获得的HTTP请求越少越好,但这会导致代码中的复杂性和重复性,除非您使用框架或工具包或自行编写。

答案 1 :(得分:1)

在性能方面,您最好使用第3个选项 - 动态创建DOM元素。首先,因为服务器响应会更小,因此更快,第二,因为JavaScript性能在创建对象时会更好。

当您只需要将元素注入页面时查看性能,比较一下:

element.appendChild(document.createElement("div"));

到此:

element.innerHTML = "<div></div>";

innerHTML更快。但是,当您需要引用注入的元素时,请比较:

var child = element.appendChild(document.createElement("div"));

到此:

element.innerHTML = "<div id=\"" + childId + "\"></div>";
var child = document.getElementById(childId);

createElement赢得了表演竞赛。

由于您需要元素引用,因此从服务器检索JSON并创建元素将获得更好的性能。

话虽如此,您可以通过仅创建需要引用的元素并在其他地方注入html来获得最佳性能。例如,对于这个html:

<div>
    <div class="a">Item A</div>
    <div class="b">Item B</div>
</div>

如果您只需要引用父<div>而不是其子代,那么不是动态创建子元素,而是动态创建父<div>,然后为其设置innerHTML含量:

var item = serverObject[i];
var el = parent.appendChild(document.createElement("div"));
el.innerHTML = "<div class=\"" + 
    item.A.className + "\">" +
    item.A.text + "</div><div class=\"" +
    item.B.className + "\">" +
    item.B.text + "</div>";

因此,你可以从性能方面获得两全其美的效果。

修改 - 添加超出性能考虑因素的信息

从架构上讲,我不喜欢服务了解客户端,只了解它提供的数据。这样,如果您决定更改UI,则不必使用该服务来使其吐出不同的HTML。此外,如果您发现要在其他地方使用相同的数据,您已经获得了可以重复使用的服务。