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/
hooray.github.io