zoukankan      html  css  js  c++  java
  • EonerCMS——做一个仿桌面系统的CMS(四)

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

    窗口拖动&改变窗口尺寸

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

      HTML代码如下:

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

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

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

    $().ready(function(){
    	$("#movedemo").data("info",{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({_w,height:_h,left:_l,top:_t});
    		});
    	});
    	$(document).bind("mouseup",function(){
    		$(this).unbind("mousemove");
    		$("#movedemo").data("info",{$("#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群里对我的问题给予解答

  • 相关阅读:
    python--函数的返回值、函数的参数
    python--字典,解包
    Vue--ElementUI实现头部组件和左侧组件效果
    Vue--整体页面布局
    jmeter--non GUI
    python--切片,字符串操作
    celery--调用异步任务的三种方法和task参数
    celery--实现异步任务
    celery--介绍
    开发问题记录
  • 原文地址:https://www.cnblogs.com/hooray/p/2193711.html
Copyright © 2011-2022 走看看