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

  拖动实现的思路已经更新,为防止大家步入误区,本文建议不用阅读太细,实现思路请参考:http://www.cnblogs.com/hooray/archive/2012/03/23/2414410.html

图标拖动排序

  最近加了一个人,给我提了不少意见,也帮了测了一些bug,这次要说的更新就是图标拖动排序的功能。开始我以为实现会很难,当动手开始做的时候,发现也不过如此。下面我就一点点把我的思路告诉大家。

  首先,图标拖动和窗口拖动的实现代码是几乎一样的,如果你对这个不清楚,可以看下我之前写的文章《EonerCMS——做一个仿桌面系统的CMS(四)》,关于拖动时的样式效果,我都是以win7做为参考,如图

  当我们在拖动一个图标的时候,原图标不动,然后复制出一个与其一样半透明的图标,然后放开鼠标,删除原先的位置,更新到移动后的位置,如图

  思路清楚后,就可以动手开始做了,首先是复制一个半透明图标,触发事件是在我鼠标左键mousedown的时候

	$(document).on("mousedown","#desk ul li",function(e){
		$(document.body).append('<li id="shortcut_shadow" style="position:absolute;display:none">'+$(this).html()+'</li>');
		...
		...
	});

  注意看,当我mousedown的时候,复制出来的半透明图标是不显示的,显示是在当鼠标按住拖动时才显示出来的

	$(document).on("mousedown","#desk ul li",function(e){
		$(document.body).append('<li id="shortcut_shadow" style="position:absolute;display:none">'+$(this).html()+'</li>');
		var obj = $('#shortcut_shadow');
		...
		...
		//增加背景遮罩层
		_cache.MoveLayOut = GetLayOutBox();
		var lay = ($.browser.msie) ? _cache.MoveLayOut : $(window);	
		//绑定鼠标移动事件
		lay.off("mousemove").on("mousemove",function(e){
			obj.show();
		});
	});

  当然,只要是拖动的功能,我都会增加一个透明背景遮罩层,避免触发桌面上的一些点击事件或hover效果,拖动的完整代码如下

	$(document).on("mousedown","#desk ul li",function(e){
		$(document.body).append('<li id="shortcut_shadow" style="position:absolute;display:none">'+$(this).html()+'</li>');
		var obj = $('#shortcut_shadow');
		var oldobj = $(this);
		x = e.screenX;	//鼠标位于屏幕的left
		y = e.screenY;	//鼠标位于屏幕的top
		sT = $(this).offset().top;
		sL = $(this).offset().left;
		//增加背景遮罩层
		_cache.MoveLayOut = GetLayOutBox();
		var lay = ($.browser.msie) ? _cache.MoveLayOut : $(window);	
		//绑定鼠标移动事件
		lay.off("mousemove").on("mousemove",function(e){
			obj.show();
			_cache.MoveLayOut.show();
			eX = e.screenX;	//鼠标位于屏幕的left
			eY = e.screenY;	//鼠标位于屏幕的top
			lessX = eX - x;	//距初始位置的偏移量
			lessY = eY - y;	//距初始位置的偏移量
			_l = sL + lessX;
			_t = sT + lessY;
			obj.css({left:_l,top:_t}).attr("left",_l).attr("top",_t);
		});
	});

  接下来要做的就是,当鼠标抬起的时候,更新图标位置,事件就是mouseup。功能实现的思路是这样,因为我之前写过窗口的resize事件,resize事件会重新对页面上的所有图标更新显示位置,但他是根据图标代码顺序来进行排序的,这个专业名词好像是叫DOM树。也就是我需要做的就是更新图标的dom树,这时页面上是看不出变化的,然后通过resize事件刷新页面上的图标排序,通过2张图来看下就会比较明白了。

  这时更新的dom树,但没有调用resize事件,所以虽然代码顺序上是变了,但因为图标是绝对定位,所以页面上是看不出变化的。这时我们在调用下resize事件看看

  关于如何计算图标移动到什么位置,就是获得那个半透明图标的当前位置,然后计算出当前位置在图标的dom树里是第几个,然后删除原先图标的节点,添加新节点到最新位置即可,具体可以看下完整实现代码

	//绑定鼠标抬起事件
	lay.off("mouseup").on("mouseup",function(){
		_cache.MoveLayOut.hide();
		obj.remove();
		if($.browser.msie){
			_cache.MoveLayOut[0].releaseCapture();
		}
		$(this).off("mousemove");
		//移动图标
		var num = parseFloat((parseInt(obj.attr("top"))-Core.config.shortcutTop)/90);
		if(!isNaN(num)){
			var arowcount = parseInt(($(window).height()-Core.config.shortcutTop)/90);
			num += parseInt((parseInt(obj.attr("left"))+40-Core.config.shortcutLeft)/90)*arowcount;
			num = num >= $("#desk ul li:last").index() ? $("#desk ul li:last").index() : num;
			//如果图标位置有变动则更新
			if(oldobj.index() != parseInt(num)){
				//更新dom
				if(num<=0){
					$("#desk ul li:eq(0)").before(oldobj);
				}else{
					$("#desk ul li:eq("+parseInt(num)+")").after(oldobj);
				}
				//调用resize方法刷新页面图标坐标
				Core.resize(0);
				//更新数据库图标排序(ajax)-待完成
			}
		}
	});

  注:“num”就是半透明图标处于图标dom树第几个的位置,因为图标排列是一列一列的,计算公式大致就是:(每列个数*(当前处于第几列-1))+当前处于某列第几个

  这次就更新了这么一个大功能,然后修改了一些小的建议,就不列举了。测试地址:http://saw.caifutang.com/eonercms/

posted @ 2011-12-07 02:11  胡尐睿丶  阅读(4126)  评论(14编辑  收藏  举报