JavaScript/RIA/User Interface

使用DomHelper 创建元素的DOM、HTML片断和模版

2008-04-14:01-04-27

今晚我对prototype+Scriptaculous和 MochiKit's那个不错的DOM处理库进行的轮流测试,测试结果让我感觉好几次的意外。 读者可自行分析一下的成绩,结果很难令人信服。

在JavaScript的开发过程,某些原因你需要用DOM来创建元素。处理这些元素很可能会是一段又长有臃肿的代码,花费了不少时间而仅仅只是干一些鸡毛蒜皮的话,那就不值了。而且,用DOM创建这些元素的性能上并不高效,尤其是IE上面。要想即高效又能支持标准的话,任何DOM的创建类都应该支持DOM和HTML片断。HTML片断在IE中跑得很快,最快可跑到比原来快300%的速度。包含在版本 0.32.2中,那个可提取DOM层的DomHelper,就能通过DOM创建元素,或HTML片断,也能把你的DOM代码变成HTML片断的模版。

简单的例子

为了让我少打点字,下面的的例子假设有这么一个变量dh,就是代表了YAHOO.ext.DomHelper。

var dh = YAHOO.ext.DomHelper;

我们看看这个简单例子:

// 元素’my-div’可以是一个ID或某个实际节点

var list = dh.append('my-div', {tag: 'ul', cls: 'my-list'});

上面说了DomHelper能处理DOM或HTML片断,这用起来很方便,好像这样子便是添加了一个元素。这是一个极好的功能,而你不必像以前那样,新建它再加入内容。让我们把这个例子摊开来看:

var list = dh.append('my-div', {

	tag: 'ul', cls: 'my-list', children: [
	
	{tag: 'li', id: 'item0', html: 'List Item 0'}, 
	
	{tag: 'li', id: 'item1', html: 'List Item 1'}, 
	
	{tag: 'li', id: 'item2', html: 'List Item 2'}, 
	
	{tag: 'li', id: 'item3', html: 'List Item 3'}, 
	
	{tag: 'li', id: 'item4', html: 'List Item 4'}
	
	]

});

传递到对象“o”的所有属性都假设为元素的节点,除了下面四个属性: tag –元素的名称 children -对象的定义是数组类型,包含有相同特征的一类元素。 这里你可尽情地嵌套 cls - 元素的class属性。Class是一个保留字,className又太长了。 html – 元素的innerHTML

下列是一些插入方法:

  • append( el,o)- Creates new DOM element(s) defined by o and appends them to el
  • insertBefore( el,o)- Creates new DOM element(s) defined by o and inserts them before el
  • insertAfter( el,o)- Creates new DOM element(s) defined by o and inserts them after el
  • overwrite( el,o)- Creates new DOM element(s) defined by o and overwrites the contents of el with them
  • createTemplate(o)- Creates a template from the DOM element(s) defined by o (See below)
  • insertHtml( where, el, html) - Inserts fragments into the DOM. It supports four insertion points related to el (which are named after the same points in IE's insertAdjacentHTML): beforeBegin, afterBegin, beforeEnd, afterEnd.

嗯 我已经明白这些了,还要什么特别要注意的吗? 使用上述方法创建你的元素,DomHelper会尽可能地使用HTML片断,这会比DOM操作带来性能上极大的提升。但你不想这样的话,可强制使用DOM:

YAHOO.ext.DomHelper.useDom = true; 

真正强大的是内建 版。“o”这个参数与其它所有方法一样,有相同的语法,但用在createTemplate()的时候,它不会创建或添加任何元素。插入这个元素会返回一个反复循环产生新元素的模版对象。让我们对比一下上面的例子,然后这次使用模版:

var list = dh.append('my-div', {tag: 'ul', cls: 'my-list'});
var tpl = dh.createTemplate({tag: 'li', id: 'item{0}', html: 'List Item {0}'});
for(var i = 0; i < 5, i++){	tpl.append(list, [i]);}

模版对象支持相同的DomHelper插入方式。第二个插入方法的参数既可以是数组array(像上面的例子就是数字式的模版参数) 或一个对象(命名式参数) 模版对象也可以这样子用:

var html = '{2}';
var tpl = new YAHOO.ext.DomHelper.Template(html);
tpl.append('blog-roll', ['link1', 'http://www.jackslocum.com/', "Jack's Site"]);
tpl.append('blog-roll', ['link2', 'http://www.dustindiaz.com/', "Dustin's Site"]);

同一个例子,不过是(named parameters)的:

var html = '{text}';
var tpl = new YAHOO.ext.DomHelper.Template(html);tpl.append('blog-roll', { id: 'link1', url: 'http://www.jackslocum.com/', text: "Jack's Site"}); tpl.append('blog-roll', { id: 'link2', url: 'http://www.dustindiaz.com/', text: "Dustin's Site"});

编译模版

在模版中用正则表达式可能不会让你意外。当前的性能已经不错了,但若然你有一大捆的DOM元素要加入的话,“编译”那个模版更能提升性能。The way "compile()" works is the template is parsed and broken up at the different variable points and a dynamic function is created and eval'ed. The generated function performs string concatenation of these parts and the passed variables instead of using regular expressions.

var html = '{text}';
var tpl = new YAHOO.ext.DomHelper.Template(html);tpl.compile();
//... use template like normal

基准测试

我做了一些基准测试,看看各种方式的区别。在循环1000次的产生3000个元素的循环中,执行了下面的代码,同样,对不用模版也进行了测试。

var spec = {
	tag: 'div',		style: 'width:100%;border:1px solid blue;',		cls: 'wtf', 	
	children: [{		tag: 'a',				href: '{url}',				children: [{					tag: 'span',		
			html: '{text}'		}]	}]};
var template = YAHOO.ext.DomHelper.createTemplate(spec);

下面是浏览器的平均时间。注意IE6的极大分别,从1.35到.300。这样的性能真令人觉得IE6的执行DOM的组件是用VB写的。Opera9的成绩始终是保持得最好的,

Insertion Method

IE7 beta 2

IE6

FF 1.5

Opera 9

DOM

.730

1.35

.420

.280

HTML Fragments

.360

.380

.400

.260

Template

.320

.335

.385

.220

Compiled Template

.295

.300

.350

.210

整体性能的提升已经足够给工作带来不少好处了。使我迫不及待地,把编译好的模版,改写到Grid组件中去。

评论列表

没有记录

名称:

Email 第三者保密

网站:


你的评论:

点击以刷新图片 为防止SPAM信息,请劳烦输入验证码。
关于我们
本站是一个小型技术类博客,专门发表前端用户交互技术方面的文章,致力于人机交互的研究。 除了特别声明转载的文章外,其余均属于我们个人原创。 有关Rich Internet Application,会发表一些热门的技巧、优秀的应用以及RIA最新的发展状况。 以前是经常Javaeye Ajax版潜水,由于资源分得比较散,不好整合,所以独立出来。网站还没有完全成型,希望大家留下宝贵的建议。
“What the web can be.”
最新文章