EonerCMS——做一个仿桌面系统的CMS(四)

简介:

  一晃又过去一个多星期了,途中出了个差,进度上略有耽误,不过还好,上次有个话题没说完,这次继续,就是窗口拖动以及改变窗口尺寸。

窗口拖动&改变窗口尺寸

  因为这功能可能很多人都做过,所以我只是提供一种我的方法,当然如果有考虑不全的地方,希望大家能提出来,因为拖动层的功能我是第一次做,没太多经验,也请教了很多人。接下来就先看demo吧:

  HTML代码如下:

< div  id="movedemo">
     < div  class="titledemo">按住我拖动</ div >
     < div  style="position:absolute;overflow:hidden;top:-3px;width:100%;height:5px;z-index:1;cursor:n-resize" resize="t"></ div >
     < div  style="position:absolute;overflow:hidden;right:-3px;width:5px;height:100%;z-index:1;cursor:e-resize" resize="r"></ div >
     < div  style="position:absolute;overflow:hidden;bottom:-3px;width:100%;height:5px;z-index:1;cursor:s-resize" resize="b"></ div >
     < div  style="position:absolute;overflow:hidden;left:-3px;width:5px;height:100%;z-index:1;cursor:w-resize" resize="l"></ div >
     < div  style="position:absolute;overflow:hidden;right:-3px;top:-3px;width:10px;height:10px;z-index:2;cursor:ne-resize" resize="rt"></ div >
     < div  style="position:absolute;overflow:hidden;right:-3px;bottom:-3px;width:10px;height:10px;z-index:2;cursor:se-resize" resize="rb"></ div >
     < div  style="position:absolute;overflow:hidden;left:-3px;top:-3px;width:10px;height:10px;z-index:2;cursor:nw-resize" resize="lt"></ div >
     < div  style="position:absolute;overflow:hidden;left:-3px;bottom:-3px;width:10px;height:10px;z-index:2;cursor:sw-resize" resize="lb"></ div >
</ div >

  在#movedemo里包了8个div,具体功能就不介绍了,不明白了去看我上一篇文章《EonerCMS——做一个仿桌面系统的CMS(三)》,我在那里对这个做了具体说明。

  JS代码是重点,我对几个变量标明了注释,方便大家能看懂:

$().ready( function (){
     $( "#movedemo" ).data( "info" ,{width:100,height:100,left:0,top:0});
     $( ".titledemo" ).bind( "mousedown" , function (e){
         x = e.screenX;  //鼠标位于屏幕的left
         y = e.screenY;  //鼠标位于屏幕的top
         sT = $( "#movedemo" ).offset().top;
         sL = $( "#movedemo" ).offset().left;
         $(document).bind( "mousemove" , function (e){
             eX = e.screenX; //鼠标位于屏幕的left
             eY = e.screenY; //鼠标位于屏幕的top
             lessX = eX - x; //距初始位置的偏移量
             lessY = eY - y; //距初始位置的偏移量
             _l = sL + lessX;
             _t = sT + lessY;
             _w = $( "#movedemo" ).data( "info" ).width+ "px" ;
             _h = $( "#movedemo" ).data( "info" ).height+ "px" ;
             $( "#movedemo" ).css({width:_w,height:_h,left:_l,top:_t});
         });
     });
     $(document).bind( "mouseup" , function (){
         $( this ).unbind( "mousemove" );
         $( "#movedemo" ).data( "info" ,{width:$( "#movedemo" ).width(),height:$( "#movedemo" ).height()});
     });
     var  moveline = {
         't' : '' ,
         'r' : '' ,
         'b' : '' ,
         'l' : '' ,
         'rt' : '' ,
         'rb' : '' ,
         'lt' : '' ,
         'lb' : ''
     };
     var  ml= "" ;
     for (ml in  moveline){
         //依次绑定8个方向的缩放拖动事件
         bindResize(ml);
     }
});
 
function  bindResize(ml){
     $( "#movedemo div[resize='" +ml+ "']" ).bind( "mousedown" , function (e){
         x=(e.offsetX==undefined) ? getOffset(e).offsetX : e.offsetX ;
         y=(e.offsetY==undefined) ? getOffset(e).offsetY : e.offsetY ;
         cy = e.clientY;
         cx = e.clientX;
         h = $( "#movedemo" ).height();
         w = $( "#movedemo" ).width();
         $(document).unbind( "mousemove" ).bind( "mousemove" , function (e){
             switch (ml){
                 case  "t" :
                     if (h+cy-e.clientY>50){
                         $( "#movedemo" ).css( "height" ,h+cy-e.clientY).css( "top" ,e.clientY-y);
                     }
                 break ;
                 case  "r" :
                     if (w-cx+e.clientX>100){
                         $( "#movedemo" ).css( "width" ,w-cx+e.clientX);
                     }
                 break ;
                 case  "b" :
                     if (h-cy+e.clientY>50){
                         $( "#movedemo" ).css( "height" ,h-cy+e.clientY);
                     }
                 break ;
                 case  "l" :
                     if (w+cx-e.clientX>100){
                         $( "#movedemo" ).css( "width" ,w+cx-e.clientX).css( "left" ,e.clientX-x);
                     }
                 break ;
                 case  "rt" :
                     if (h+cy-e.clientY>50){
                         $( "#movedemo" ).css( "height" ,h+cy-e.clientY).css( "top" ,e.clientY-y);
                     }
                     if (w-cx+e.clientX>100){
                         $( "#movedemo" ).css( "width" ,w-cx+e.clientX);
                     }
                 break ;
                 case  "rb" :
                     if (w-cx+e.clientX>100){
                         $( "#movedemo" ).css( "width" ,w-cx+e.clientX);
                     }
                     if (h-cy+e.clientY>50){
                         $( "#movedemo" ).css( "height" ,h-cy+e.clientY);
                     }
                 break ;
                 case  "lt" :
                     if (w+cx-e.clientX>100){
                         $( "#movedemo" ).css( "width" ,w+cx-e.clientX).css( "left" ,e.clientX-x);
                     }
                     if (h+cy-e.clientY>50){
                         $( "#movedemo" ).css( "height" ,h+cy-e.clientY).css( "top" ,e.clientY-y);
                     }
                 break ;
                 case  "lb" :
                     if (w+cx-e.clientX>100){
                         $( "#movedemo" ).css( "width" ,w+cx-e.clientX).css( "left" ,e.clientX-x);
                     }
                     if (h-cy+e.clientY>50){
                         $( "#movedemo" ).css( "height" ,h-cy+e.clientY);
                     }
                 break ;
             }
         });
     });
}
 
function  getOffset(e){
     var  target = e.target;
     if  (target.offsetLeft == undefined){
         target = target.parentNode;
     }
     var  pageCoord = getPageCoord(target);
     var  eventCoord ={
         x: window.pageXOffset + e.clientX,
         y: window.pageYOffset + e.clientY
     };
     var  offset = {
         offsetX: eventCoord.x - pageCoord.x,
         offsetY: eventCoord.y - pageCoord.y
     };
     return  offset;
}
function  getPageCoord(element){
     var  coord = {x:0, y:0};
     while (element){
         coord.x += element.offsetLeft;
         coord.y += element.offsetTop;
         element = element.offsetParent;
     }
     return  coord;
}

  首先我给可拖动的窗口加了个data属性,用来存放width、height、top、left四个属性值,在每次移动或者改变尺寸,都对这个值进行更新并存放,目的就是当窗口最大化后,点还原可以还原到最大化前的尺寸和位置。

  然后我对标题栏绑定了鼠标按下去的事件,然后在事件里绑定了document的鼠标滑动事件,而不是直接对标题栏绑定滑动事件,目的就是防止出现鼠标移动过快,移除标题栏那块区域,导致拖动效果一卡一卡的现象。

  之后就是获取鼠标移动的位置,更新可拖动窗口的top和left值。

  接着就是改变窗口尺寸,我事先先对8个div绑定好事件,然后也是用类似的方法,获取鼠标位置,更新窗口的width、height、top、left的值。值得一提的是,因为火狐不认识offsetX和offsetY,所以代码最下面有2个方法,就是用来获取火狐下offset的XY值的,调用方法就是:getOffset(e).offsetX

  功能大致上就是这些了,因为是demo,所以细节需要大家去考虑,比如拖动到页面顶部,则不能再往上拖动,防止拖到浏览器外面,当然底部也一样。

尽量避免上面这种情况

底部我的做法是,最多拖动到标题的位置就不能再继续往下拖动了,大家可以参考下我这种做法

  关于左右两侧,我是参考了win7里的一个小功能,就是鼠标拖动到窗口边缘时,自动把窗口变成半屏,这样的目的就是为了之后cms系统有更高效的操作,比如我要同时操作新闻栏目和新闻文章,就可以左右两边分别打开这两个页面,然后同步操作,提高效率。

  要说的就是这么,关于拖动的demo,我提供下载地址,欢迎下载查看,因为是demo,所以没写成插件,点击下载

  PS:其实功能上大致已经OK了,我打算十一把细节优化一下,国庆放假回来我就先放出整个CMS的demo给大家看下,到时候还希望大家多多帮我提提意见,因为毕竟是一个人做的,考虑的东西不是很全。

  PS2:感谢Gray Zhang(灰哥)在某js群里对我的问题给予解答




   本文转自胡尐睿丶博客园博客,原文链接:http://www.cnblogs.com/hooray/archive/2011/09/28/2193711.html,如需转载请自行联系原作者



相关文章
|
开发框架 JavaScript 前端开发
在 linux 上搭建 express 图床服务(支持多图上传),奥利给!
在 linux 上搭建 express 图床服务(支持多图上传),奥利给!

热门文章

最新文章