日期:2014-05-16 浏览次数:20496 次
开发一个交互式的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对象,在频繁地创建和删除它们之前,都需要考虑性能上的影响。
?
?