模拟一个盒子的拖动效果

2018/03/06 21:36
阅读数 10

    博主的前端入门知识是在慕课网学的,当时有个demo,就是在网页模拟一个QQ面板的拖动效果(如图,用两个DIV代替。。。效果是拖动中间的DIV,整个DIV跟着移动),今天来总结记录一下。

    思路是当鼠标按下时,开始计算元素距离屏幕左边缘和上边缘的距离,并同步赋予元素。这里的关键点是对于JS中元素与根元素(或者指定父级元素)的距离的运用,即offset。

 

 

首先假设外层盒子叫out,中间盒子叫center。当鼠标在center按下时为out添加事件:

 

1 function drag () {
2   var center = document.getElementById('center')
3   center.onmousedown = client  // 获取中间盒子,按下鼠标时添加事件
4 }
    并且获取out的当前位置(clientX,clientY)(这里的参照系是当前窗口,若将浏览器窗口缩小,则可移动区域减小),再获取out距离窗口边缘的位置坐标(offsetLeft,offsetTop),此处没有设置参考的父元素,所以以根元素为参照物,即body。
取两者差值,就是整个DIV应该变化的坐标量。这时将out的坐标与变化量相加,就得到了整个DIV的新坐标值。用onmousemove随时更新DIV的坐标,就得到了拖动的效果。
 1 function client (eve) {
 2   eve = eve || window.event  // 兼容性
 3   var out = document.getElementById('out')
 4   var disX = eve.clientX - out.offsetLeft // 鼠标点击位置跟out块的左边框距离
 5   var disY = eve.clientY - out.offsetTop // 鼠标点击位置跟out块的上边框距离
 6   document.onmousemove = function (event) {
 7     event = event || window.event
 8     mov(event, disX, disY)
 9     console.log('eve.clientX' + eve.clientX)
10     console.log('disX' + disX)
11     console.log('out.offsetLeft' + out.offsetLeft)
12   }
13   document.onmouseup = function () {
14     document.onmousemove = null
15     document.onmouseup = null // 释放鼠标时清空事件
16   }
17 }
    为防止盒子移动到窗口外面,需要进行边缘检测,由于窗口的坐标系以屏幕左上角为原点,所以左边检测和上边检测只需要看鼠标的坐标—out距离窗口左边框(或上边框)的距离是否等于0就行。
右侧检测需要计算盒子距离左边缘的距离+盒子本身的宽度是否超过了浏览器窗口本身的宽度,浏览器本身可见区域的宽度为clientWidth,盒子本身的宽度是out.offsetWidth,这两者的差就是鼠标在x方向移动的最大值。当鼠标移动到最大值时说明盒子已经移动到了右侧屏幕边缘。底部与右侧相似。
 1 function mov (e, posx, posy) {
 2   e = e || window.event
 3   var out = document.getElementById('out')
 4   var finalLeft = e.clientX - posx // out盒子左边框距离左窗口的距离
 5   var finalHeight = e.clientY - posy // out盒子上边框距离上窗口的距离
 6   var diffWidth = document.documentElement.clientWidth - out.offsetWidth || document.body.clientWidth - out.offsetWidth  // 兼容性获取当前窗口的宽度-out盒子的宽度
 7   var diffHeight = document.documentElement.clientHeight - out.offsetHeight || document.body.clientWidth - out.offsetWidth  // 兼容性获取当前窗口的高度-out盒子的高度
 8   if (finalLeft <= 0) {
 9     finalLeft = 0
10   }
11   if (finalHeight <= 0) {
12     finalHeight = 0
13   }
14   if (finalLeft >= diffWidth) {
15     finalLeft = diffWidth
16   }
17   if (finalHeight >= diffHeight) {
18     finalHeight = diffHeight
19   }  // 设置坐标,使盒子不超出窗口
20   out.style.left = finalLeft + 'px'
21   out.style.top = finalHeight + 'px'
22 }
23 window.onload = drag

 

  
展开阅读全文
eve
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部