Javascript 的函数式对象(八)DOM对象管理器

开发一个交互式的Web页面,用来显示信息或接受用户输入的对话框必不可少。

 

对话框的创建对应着页面上若干DOM节点的生成和插入,考虑到移除这些DOM节点的开销,

 

对话框的关闭只是将这些DOM节点在页面上设置为不显示。下面是一个js生成对话框的示例:

 

var Dialog = function(){
	
	this.element = document.createElement('div'); //创建对话框对应的DOM节点
	this.element.style.display = 'none'; // 指定div不显示
	this.element.style.position = 'absolute'; // 指定div的定位模式为绝对坐标模式
	this.element.style.border = 'gray solid'; //为Dialog加上灰色的边框
	this.element.className = 'dialog';
	// 在页面的body标签中插入刚创建的div标签
	document.getElementsByTagName('body')[0].appendChild(this.element);
};

Dialog.prototype = { //将无状态方法定义在Dialog对象的原型中
	show: function(x,y, contentHTML){
		//将传入的HTML字符串作为对话框内容,插入到新创建的div标签里
		this.element.innerHTML = contentHTML;
		this.element.style.left = x + 'px'; //指定div标签左侧的坐标
		this.element.style.top = y + 'px'; //指定div标签顶端的坐标
		this.element.style.display = 'block'; // 指定div显示
	},
	
	hide: function(){
		this.element.style.display = 'none'; // 指定div不显示
	},
	
	isVisible: function(){
		if(this.element.style.display == 'none'){
			return false;
		}else return true;
	}
};

var myDialog = new Dialog();
myDialog.show(200,100, '<h1>This is a dialog!</h1>');

 

上述代码虽然避免了移除对话框的DOM节点带来的开销,但是创建对话框DOM节点的过程依然会带来开销。

 

如果用户不断地重复“打开”+“关闭”对话框这一操作,大量DOM节点的产生,将迟滞浏览器响应速度,影响用户体验,

 

在DOM树结构较为复杂的页面上,尤为明显(早期的ExtJS上也曾出现过类似问题,在后来的版本中得以修正)。

 

下面这段代码将创建一个对话框对象管理器,托管页面上的所有对话框,其原理类似线程池:

 

当需要一个对话框显示内容的时候,首先遍历管理器,如果存在未被使用的对话框,这个对话框将用来显示内容。

 

如果当前所有的对话框都处在被使用的状态,则管理器负责新建一个对话框用来显示内容,并加入管理队列。

 

//定义对话框管理器,重用已创建的对话框。当管理器中的对话框不足时,将创建新的对话框
var DialogManager = (function(){

	var createdDialogs = []; //利用闭包创建的私有数组,
	
	return {
		display: function(x, y, contentHTML){
			//遍历管理器中的对话框,如果存在没有被使用的对话框,则用它显示内容,
			var hiddenIndex = 0;
			for(var i=0, len=createdDialogs.length; i<len; i++ ){
				
				if(!createdDialogs[i].isVisible()){
					createdDialogs[i].show(x, y, contentHTML);
					hiddenIndex = i;
					break;
				}
			}
			//如果所有对话框都处于显示的状态,那么创建一个新的对话框用于显示内容
			if(hiddenIndex == 0){
				var newDialog = new Dialog();
				newDialog.show(x, y, contentHTML);
				createdDialogs.push(newDialog);
				console.log('Dialog '+createdDialogs.length+' has been created!');
			}
		}
	}
})();

//调用管理器显示对话框内容
DialogManager.display(300,200,'<h1>This is a managed dialog!</h1>');
DialogManager.display(300,300,'<h1>This is another managed dialog!</h1>');

 

在涉及到DOM节点的创建和删除这类对性能有较大影响的操作时,对它们生命周期的托管是所有js框架的重要内容。

 

甚至大型js对象本身,如一些包含复杂数据类型的json对象,在频繁地创建和删除它们之前,都需要考虑性能上的影响。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值