web开发中经常需要用用js来模拟 windows的窗口,所以就开发了一个XWindows的javascript类。
demo演示效果如下:

用mootools做为基础类库。本来打算把状态控制改写成状态模式,不过暂时没有兴趣了:)
源代码贴点:

XWindowStatus = new Class(...{ //status's manager
isMax : false,
isMin : false,
isNormal: false,
father : null,

initialize : function(father)...{
this.father = father;
},

setMax : function()...{
this.isMin = false;
this.isNormal = false;
this.isMax = true;
this.setIconState();
},

setMin : function()...{
this.isMin = true;
this.isNormal = false;
this.isMax = false;
this.setIconState();
},

setNormal: function()...{
this.isMin = false;
this.isNormal =true;
this.isMax = false;
this.setIconState();
},

setIconState: function()...{
//reset
this.father.iconMax.className = 'icon_max';
this.father.iconMin.className = 'icon_min';
//set

switch (true) ...{
case this.isMin:
this.father.iconMin.className = 'icon_revert';
break;
case this.isMax:
this.father.iconMax.className = 'icon_revert';
break;
}
}
});

XWindow = new Class(...{
containerId : null, //container id
container : null, //container div

/**//*controls*/
windowBody : null, //body div
windowFooter : null, //footer div
windowTitle : null, //title div
windowTitleSpan : null, //title text span
contentBody : null, //content div
contentIframe: null, //iframe
iconClose : null, // close icon
iconMin : null, // minize icon
iconMax : null, // to max icon

/**//*end of controls*/
mover : null, //object of Drag.Move
resizer : null, //object of Drag.Base
backup : null, //type Object for backup data such as this.backup.xx = xx;
status : null, //type WindowStatus

initialize : function (elementId) ...{
this.container = $(elementId);
this.containerId = elementId;

this.initCtrl();
this.initEvent();
this.initMisc();

this.mover = new Drag.Move(this.container,...{handle:this.windowTitle});

this.resizer = new Drag.Base(this.container, ...{
handle : this.windowBody,

modifiers : ...{x:'width', y:'height'},
onDrag : this.adjustSize.bind(this)
});
},

initCtrl : function()...{
this.windowBody = this.getChild('window_body');
this.windowTitle = this.getChild('window_title');
this.windowFooter = this.getChild('window_footer');
this.contentBody = this.getChild('content_body');
this.contentIframe= this.getChild('app_iframe','iframe');
this.iconMax = this.getChild('icon_max','em');
this.iconMin = this.getChild('icon_min','em');
this.iconClose = this.getChild('icon_close','em');
this.windowTitleSpan = this.getChild('title_span','span');
},

initEvent : function()...{
this.windowTitle.addEvent('dblclick',this.toggleMax.bind(this));
this.iconMax.addEvent('click',this.toggleMax.bind(this));
this.iconMin.addEvent('click',this.toggleMin.bind(this));
this.iconClose.addEvent('click',this.close.bind(this));
},

initMisc : function()...{
this.backup = new Object();
this.status = new XWindowStatus(this);
//data for using next
this.windowTitle.iHeight = this.windowTitle.getStyle('height').toInt();//it's constant when created
this.windowFooter.iHeight = this.windowFooter.getStyle('height').toInt();//it's constant when created
},

getChild : function(className,tagName)...{
tagName = tagName || 'div';
var selector = '#' + this.containerId + ' ' + tagName + '.' + className;
return $$(selector)[0];
},

adjustSize : function () ...{
//just need to resize height, width don't need, because set width 100% can manage it
var h = this.container.getStyle('height').toInt();
var nHeight = h - this.windowTitle.iHeight - this.windowFooter.iHeight;
if(nHeight < 12 ) nHeight = 12; //prevent less than 0
this.contentBody.setStyle('height',nHeight - 12);
this.contentIframe.setStyle('height',nHeight - 12);
},

resizeTo : function (width,height)...{
this.container.setStyle('width' ,width.toInt());
this.container.setStyle('height',height.toInt());
this.adjustSize();
this.fireEvent('resize',[width,height]);
},

moveTo : function (x,y)...{
this.container.setStyle('left',x);
this.container.setStyle('top',y);
this.fireEvent('move',[x,y]);
},

normal : function ()...{ // back to last state
var state = this.getLastState();
this.moveTo(state.x,state.y);
this.resizeTo(state.w,state.h);
this.status.setNormal(this);
this.fireEvent('normal');
},

max : function()...{
this.trackState();
this.resizeTo(window.getWidth(), window.getHeight());
this.moveTo(0,0);
this.status.setMax(this);
this.fireEvent('max');
},

min : function()...{
this.trackState();
var ih = this.windowTitle.iHeight + this.windowFooter.iHeight + 3;
this.resizeTo(200,ih);
this.moveTo(0,window.getHeight()-ih);
this.status.setMin(this);
this.fireEvent('min');
},

close : function() ...{
this.hide();
this.fireEvent('close');
},

toggleMin : function()...{
(this.status.isMin ? this.normal : this.min).apply(this);
},

toggleMax : function()...{
(this.status.isMax ? this.normal : this.max).apply(this);
},

trackState : function() ...{ // private record last state of window
if(this.status.isMax || this.status.isMin) return; // if max or min don't need to record pos or size
this.backup.last_pos = this.getPosition();
this.backup.last_size = this.getSize();
},

getLastState: function() ...{ //get last state of window
var p = this.backup.last_pos;
var s = this.backup.last_size;

return ...{'x':p.x,'y':p.y,'w':s.x,'h':s.y};
},

hide : function()...{
this.container.style.display = 'none';
this.fireEvent('hide');
},

show : function()...{
this.container.style.display = '';
this.fireEvent('show');
},

getPosition : function() ...{
return this.container.getPosition();
},

getSize : function() ...{
return this.container.getSize()['size'];
},

setTitle : function(txt)...{
this.windowTitleSpan.innerHTML = txt;
}
}).extend(new Events);
demo和源代码下载 (一个免费的网络文件存储,链接无效请联系本人)
发表于 @ 2008年01月23日 13:38:00|评论(loading...)|编辑