上次总结了一下简单的浮出层的设计,不了解的可以猛戳下面这条链接:
这次的这篇总结主要是参考的这篇文章:js拖拽事件实例,不过自己多做了一点分析
这次来总结一下浮出层的拖拽,期间遇到了一些小问题,不过最后也解决了,这里也总结一下。
首先,我们要实现的效果是浮出层在鼠标点击之后随着鼠标移动,松开之后停止移动,并且边框不得超出边界。
网上很多教程已经说得很清楚了,这里就再啰嗦两句,这个过程总共分为三步:
- 鼠标点下之时用onmousedown事件记录鼠标点下时与浮出层的相对位置
- 用onmousemove事件让浮出层跟随鼠标移动,每当用户将鼠标移动一个像素,就会发生一个 mousemove 事件,我们在这个事件中改变浮出层的位置即可
- 用onmouseup事件在鼠标松开时清除onmousemove中的事件
还需要一些额外的知识,是关于offsetWidth,offsetLeft等等,在网上找到一篇文章不错(图画的比较清楚),链接如下:
关于offsetWidth、offsetLeft等概念的理解
接下来是代码实现:
1、计算鼠标与浮出层的相对位置
horizen.onmousedown=function(ev) //鼠标按下浮出层 { var oEvent=ev||event;//这里是为了浏览器兼容,大家可以上网去查一下
disX=oEvent.clientX-horizen.offsetLeft; /*鼠标的X坐标减去浮出层的左边距就等于disX, 这个disX是用于确定鼠标移动浮出层时鼠标点和浮出层之间的左面距离,
这个距离是不会变的,通过这个新鼠标的X坐标减去disX就是浮出层的Left*/ disY=oEvent.clientY-horizen.offsetTop;
……
……
}
- 其中的clientX是鼠标相对于整个屏幕在X轴上的位置,clientY是鼠标相对于整个屏幕在Y轴上的位置
2、根据鼠标的移动计算出浮出层的offsetLeft应有的距离,从而改变浮出层的位置,并根据此距离判断浮出层是否超出边界
horizen.onmousedown=function(ev) { var oEvent=ev||event; disX=oEvent.clientX-horizen.offsetLeft; disY=oEvent.clientY-horizen.offsetTop; document.onmousemove=function(ev) { var oEvent=ev||event; //此处是为了浏览器兼容,大家可以上网去查一下 var oLeft=oEvent.clientX-disX; //新鼠标X坐标减去disX,也就是鼠标移动浮出层后的Left var oTop=oEvent.clientY-disY; if(oLeft<0) //浮出层的Left小于0,也就是移出了左边 { oLeft=0; //就把浮出层的Left设置为0,就不能移出左边 } else if(oLeft>document.documentElement.clientWidth-horizen.offsetWidth) //屏幕宽度减去浮出层的宽度就得出了浮出层到达最右边的宽度 { oLeft=document.documentElement.clientWidth-horizen.offsetWidth; //如果Left大于这个像素,就把Left设置为这个像素 } if(oTop<0) { oTop=0; } else if(oTop>document.documentElement.clientHeight-horizen.offsetHeight) { oTop=document.documentElement.clientHeight-horizen.offsetHeight; } console.log(oLeft); horizen.style.left=oLeft+'px'; //浮出层的Left设置为新鼠标X坐标减去disX的值 horizen.style.top=oTop+'px'; }; return false; //阻止FireFox的默认事件 bug,(额……不太理解,有大神知道希望赐教) }
- 以上注释只写了左右的,上下的是一样的
3.鼠标松开时清除onmousemove中的事件
document.onmouseup=function() //鼠标松开时 { document.onmousemove=null; //把鼠标移动清除 };
这样我们的浮出层的拖拽就做好了……
一切看似如此完美,可是当我打开浏览器调试的时候却发现,浮出层左边拖拽时会超出边界,右边会到达不了边界,上下也是这样
浏览器也并没有报错,检查了代码也没有错误,最后打了个断点调试了一下,发现在计算鼠标相对位置时,disX(只讨论x轴上的)的值比较小,究其原因是因为offsetLeft过大,上网查了一下以后发现,原来是translate的原因,元素利用translate移动后不会影响offsetLeft的值,意思就是它是按我向左移动前的那个浮出层计算offsetLeft的,那么offset的值自然就会变大了,并且其变大的值就是我向左移动的值(浮出层的width是400px;我想左移动了自身的50%也就是200px),所以我们需要对判定的条件进行一些修改:
if(oLeft<200) //移动前浮出层的Left小于200,也就是移出左边 { oLeft=0; //就把浮出层的Left设置为200,就不能移出左边 } else if(oLeft>document.documentElement.clientWidth-horizen.offsetWidth+200) //屏幕宽度减去DIV的宽度就得出了浮出层到达最右边的宽度, { oLeft=document.documentElement.clientWidth-horizen.offsetWidth+200; //如果Left大于这个值就把Left设置为这个值 }
上下也根据浮出层的高度改一下就可以了
这样我们的浮出层拖拽的效果就真的做好了~