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