EonerCMS——做一个仿桌面系统的CMS(三)
轉(zhuǎn)眼似乎半個(gè)多月過去了,最近忙了點(diǎn)其他的事,所以這個(gè)CMS做的進(jìn)度也慢了,不過昨天和今天稍微加了點(diǎn)班,把最大的一塊制作OK了,也就是下面我要說的——
窗口
先看下窗口大致構(gòu)成圖吧:
窗口很簡(jiǎn)單,頂部的標(biāo)題區(qū)域、中間的展示區(qū)域和底部的功能區(qū)域。首先,窗口肯定是通過圖標(biāo)點(diǎn)擊后才生成的,也就是窗口不是事先加載并隱藏好,是點(diǎn)擊某個(gè)圖標(biāo)后再通過jquery寫入到頁(yè)面里來,那我們要做的就是給圖標(biāo)綁定一個(gè)創(chuàng)建窗口的事件,我們看下代碼:
//創(chuàng)建窗體 Core.create = function(obj){var sc = obj.attr('shortcut');var window_warp = 'window_'+shortcut[sc][0]+'_warp';var window_inner = 'window_'+shortcut[sc][0]+'_inner';var resizeTemp = '<div resize="{resize_type}" style="position:absolute;overflow:hidden;background:url(img/transparent.gif) repeat;display:block;{css}"></div>';_cache.resize = { "t":"left:0;top:-3px;width:100%;height:5px;z-index:1;cursor:n-resize","r":"right:-3px;top:0;width:5px;height:100%;z-index:1;cursor:e-resize","b":"left:0;bottom:-3px;width:100%;height:5px;z-index:1;cursor:s-resize","l":"left:-3px;top:0;width:5px;height:100%;z-index:1;cursor:w-resize","rt":"right:-3px;top:-3px;width:10px;height:10px;z-index:2;cursor:ne-resize","rb":"right:-3px;bottom:-3px;width:10px;height:10px;z-index:2;cursor:se-resize","lt":"left:-3px;top:-3px;width:10px;height:10px;z-index:2;cursor:nw-resize","lb":"left:-3px;bottom:-3px;width:10px;height:10px;z-index:2;cursor:sw-resize"};$('#desk').append('<div id="'+window_warp+'" window="'+shortcut[sc][0]+'" class="window-container window-current" style="width:'+shortcut[sc][4]+'px;height:'+shortcut[sc][5]+'px;top:'+shortcut[sc][6]+'px;left:'+shortcut[sc][7]+'px;z-index:'+Core.config.createIndexid+'"><div id="'+window_inner+'" style="height:100%"></div></div>');$("#"+window_warp).data("info",{width:shortcut[sc][4],height:shortcut[sc][5],top:shortcut[sc][6],left:shortcut[sc][7]});Core.config.createIndexid += 1;$('#'+window_inner).append('<div class="title-bar">'+shortcut[sc][1]+'<div class="title-handle"><a class="ha-hide" btn="hide" href="#ha-hide">最小化</a><a class="ha-max" btn="max" href="#ha-max">最大化</a><a class="ha-revert" btn="revert" href="#ha-revert" style="display:none">還原</a><a class="ha-close" btn="close" href="#ha-close">關(guān)閉</a></div></div>');$('#'+window_inner).append('<div class="window-frame"><div style="z-index:9000000;background:none;height:100%;position:absolute;width:100%;filter:alpha(opacity=0);-moz-opacity:0;opacity:0;display:none"></div><iframe frameborder="0" id="frame'+shortcut[sc][0]+'" src="'+shortcut[sc][3]+'"></iframe></div>');$('#'+window_inner).append('<div class="set-bar"><div class="fr"><a id="refresh" class="btn"><i class="icon ico-refresh"></i><span class="btn-con">刷新</span></a></div></div>');for(var k in _cache.resize){var ele = FormatModel(resizeTemp,{resize_type:k, css:_cache.resize[k]});$('#'+window_inner).append(ele);}//綁定窗口移動(dòng)事件Core.bindWindowMove($('#'+window_warp));//綁定窗口縮放事件Core.bindWindowResize($('#'+window_warp));//綁定窗口功能按鈕事件Core.handle($('#'+window_warp)); };我們先從這里看起,因?yàn)橹暗亩x:
$('#desk').append('<div id="'+window_warp+'" window="'+shortcut[sc][0]+'" class="window-container window-current" style="width:'+shortcut[sc][4]+'px;height:'+shortcut[sc][5]+'px;top:'+shortcut[sc][6]+'px;left:'+shortcut[sc][7]+'px;z-index:'+Core.config.createIndexid+'"><div id="'+window_inner+'" style="height:100%"></div></div>'); (1)$("#"+window_warp).data("info",{width:shortcut[sc][4],height:shortcut[sc][5],top:shortcut[sc][6],left:shortcut[sc][7]}); (2)Core.config.createIndexid += 1; (3)$('#'+window_inner).append('<div class="title-bar">'+shortcut[sc][1]+'<div class="title-handle"><a class="ha-hide" btn="hide" href="#ha-hide">最小化</a><a class="ha-max" btn="max" href="#ha-max">最大化</a><a class="ha-revert" btn="revert" href="#ha-revert" style="display:none">還原</a><a class="ha-close" btn="close" href="#ha-close">關(guān)閉</a></div></div>'); (4)$('#'+window_inner).append('<div class="window-frame"><div style="z-index:9000000;background:none;height:100%;position:absolute;width:100%;filter:alpha(opacity=0);-moz-opacity:0;opacity:0;display:none"></div><iframe frameborder="0" id="frame'+shortcut[sc][0]+'" src="'+shortcut[sc][3]+'"></iframe></div>'); (5)$('#'+window_inner).append('<div class="set-bar"><div class="fr"><a id="refresh" class="btn"><i class="icon ico-refresh"></i><span class="btn-con">刷新</span></a></div></div>'); (6)(1)這里我先給#desk增加了一個(gè)div,這個(gè)div也就是整個(gè)窗體的div,并且這個(gè)窗體的是為使用狀態(tài),因?yàn)樾陆ǖ拇翱诳隙槭褂脿顟B(tài)的,不會(huì)覆蓋在其他窗口下面,所以在樣式里我寫了z-index,并且這個(gè)值不是固定死的,(3)我在添完后馬上對(duì)這個(gè)全局變量z-index進(jìn)行了加1,這樣就可以保證之后新建的窗體能出現(xiàn)在最上面。
(2)在添加完窗體后我馬上對(duì)這個(gè)窗體綁定了它的數(shù)據(jù),分別是width、height、top、left,這個(gè)之后會(huì)說有什么用,先跳過。
(4)然后我加入窗體必備的4個(gè)按鈕,最小化、最大化、還原、關(guān)閉,當(dāng)然其中還原按鈕是隱藏著的。
(5)然后我加載的iframe,用于顯示需要加載的頁(yè)面
(6)最后我加入了底部功能欄
然后看下這段代碼:
for(var k in _cache.resize){var ele = FormatModel(resizeTemp,{resize_type:k, css:_cache.resize[k]});$('#'+window_inner).append(ele);}上面我定義了一個(gè)數(shù)組(_cache.resize),這里在對(duì)它進(jìn)行循環(huán),在循環(huán)體內(nèi)我用了一個(gè)FormatModel(),這個(gè)方法我在上篇文章里提到過,就不再介紹用法了:《自己寫的一個(gè)分享按鈕的插件(可擴(kuò)展,內(nèi)附開發(fā)制作流程)》
這個(gè)數(shù)組長(zhǎng)度為8,也就是這個(gè)循環(huán)一共添加了8個(gè)div,那么這8個(gè)div到底是什么東西呢,看下這張圖就明白了:
對(duì)了,就是8個(gè)方向,相信有童鞋應(yīng)該知道是干嘛用的了,就是之后窗體縮放需要用到了,我會(huì)對(duì)這8個(gè)div分別綁定事件,讓他們實(shí)現(xiàn)對(duì)窗體大小的縮放功能。
至此,窗體添加的功能大致完畢,但還需要完善,比如同個(gè)圖標(biāo)的窗體已經(jīng)創(chuàng)建過,就不需要繼續(xù)創(chuàng)建了,而只需把窗體的樣式改變下,比如修改成使用狀態(tài),并且把z-index的值修改最高。具體代碼我就不貼出來了,留給大家去分析吧。
任務(wù)欄
創(chuàng)建窗體的同時(shí),也需要?jiǎng)?chuàng)建任務(wù)欄,代碼很簡(jiǎn)單,稍微看下吧:
$('.task-window li b').removeClass('focus');$('.task-window').append('<li window="'+shortcut[sc][0]+'"><b class="focus"><img src="'+shortcut[sc][2]+'"><span>'+shortcut[sc][1]+'</span></b></li>');原理就是在添加前,把任務(wù)欄里現(xiàn)有的任務(wù)選中樣式清除,然后添加新的任務(wù)。
切換窗口
切換窗口就是當(dāng)我同時(shí)打開2個(gè)以上窗口時(shí),直接在窗口上,或者任務(wù)欄里切換窗口的事件,功能比較簡(jiǎn)單,先看下代碼,然后我再稍微把思路說下。
//任務(wù)欄 Core.taskwindow = function(obj){var window_warp = 'window_'+obj.attr('window')+'_warp';var window_inner = 'window_'+obj.attr('window')+'_inner';//改變?nèi)蝿?wù)欄樣式$('.task-window li b').removeClass('focus');obj.children('b').addClass('focus');//改變窗口樣式$('.window-container').removeClass('window-current');$('#'+window_warp).addClass('window-current').css({'z-index':Core.config.createIndexid}).show();//改變窗口遮罩層樣式$('.window-frame').children('div').show();$('#'+window_inner+' .window-frame').children('div').hide();Core.config.createIndexid += 1; };//窗口 Core.container = function(obj){//改變?nèi)蝿?wù)欄樣式$('.task-window li b').removeClass('focus');$('.task-window li[window="'+obj.attr('window')+'"] b').addClass('focus');//改變窗口樣式$('.window-container').removeClass('window-current');obj.addClass('window-current').css({'z-index':Core.config.createIndexid});//改變窗口遮罩層樣式$('.window-frame').children('div').show();obj.find('.window-frame').children('div').hide();Core.config.createIndexid += 1; };大致思路就是,當(dāng)我點(diǎn)擊任務(wù)欄里某個(gè)任務(wù),找到與這個(gè)任務(wù)相對(duì)應(yīng)的窗口,讓它顯示并更新z-index,然后把自己修改成選中狀態(tài),同理點(diǎn)擊窗口時(shí)也會(huì)觸發(fā)一個(gè)類似這樣的事件,可以通過兩個(gè)function里的注釋看到,代碼執(zhí)行流程幾乎都是一樣的。
這里有個(gè)小技巧,還記得窗口由哪三部分構(gòu)成么?頂部、中間和底部,中間是iframe。小技巧就是,當(dāng)我創(chuàng)建窗體時(shí),給iframe加了一個(gè)div遮罩層,寬高剛好和iframe一樣,當(dāng)窗體不在使用狀態(tài)時(shí),比如被別的窗口覆蓋在下面,那個(gè)遮罩層就顯示出來,剛好把iframe蓋住,因?yàn)檎谡謱邮峭该髁?#xff0c;所以看上去沒有差異。為什么要這么做呢,因?yàn)檫@樣,在切換窗口時(shí),點(diǎn)擊事件可以不單單只寫在頂部的標(biāo)題區(qū)域,在點(diǎn)擊iframe(實(shí)際點(diǎn)擊的時(shí)遮罩層)也可以實(shí)現(xiàn)窗體切換功能,當(dāng)然,切換后要馬上把遮罩層隱掉。
今天就說要這里吧,下次我會(huì)把窗口移動(dòng)、縮放的給大家說下,之所以要單獨(dú)把這個(gè)拎出來,是因?yàn)槲疫@兩天就一直再搞這個(gè),雖然現(xiàn)在弄好了,但感覺還是有點(diǎn)問題,需要優(yōu)化的地方應(yīng)該還有很多,所以下次我會(huì)把我的疑問拋出來,同時(shí)也希望得到大神們的解答。
總結(jié)
以上是生活随笔為你收集整理的EonerCMS——做一个仿桌面系统的CMS(三)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么ORM性能比iBATIS好?
- 下一篇: getopt();getopt_long