JS实现QQ面板-拖曳效果

实现的功能是将整个QQ面板在特定区域点击鼠标按下移动,面板会随着光标移动而移动,这可以称为鼠标跟随效果,也叫拖曳效果。

首先是确定HTML结构,定义一个父元素模拟整个QQ面板,设置标题区域用于JS选中进行拖曳。

<div class="loginPanel" id="loginPanel">
    <div id="title"></div>
</div>

CSS样式,这里有一个需要注意的地方就是面板会跟随鼠标移动,涉及到坐标的问题就应该在该元素上设置绝对定位。

.loginPanel {width: 380px;height: 247px;left: 400px;top: 120px;position: absolute;border: 1px solid #ccc;background: #f6f6f6;border-radius: 10px;box-shadow: 0 0 8px #000;}
#title {background-color: #adc;width: 200px;height: 44px;cursor: move;position: absolute;top: 10px;left: 98px;}

JS部分,我们来分析一下来确定完成的思路,第一步首要的就是会想到既然是要在特定 title 区域选中鼠标按下移动,那么我们就要来获取到这个 title 元素,获取之后呢?想不到了,做一步想一步吧。

window.onload=drag;
function drag(){
  var oTitle=document.getElementById("title");
  oTitle.onmousedown=fnDown;
}

title 元素获取到之后,是进行鼠标按下移动的,这就用到了onmousedown事件,将其封装成一个函数,来具体实现。这里还是不能忘了鼠标拖曳效果的原理:面板跟随光标位置的移动而移动。我们需要用到鼠标坐标,又因为鼠标事件都是在浏览器窗口中的特定位置上发生的。这个位置信息保存在实践的clientX和clinetY属性中。它们的值表示事件发生时鼠标指针在视口中的水平和垂直坐标,不包括页面滚动的距离。之前有提过QQ面板元素需要绝对定位,那么设置它的移动就是设置top / left 值。

function fnDown(){
    var oDrag=document.getElementById('loginPanel');
    document.onmousemove=function(event){
        event = event || window.event;
        oDrag.style.left=event.clientX+"px";
        oDrag.style.top=event.clientY+"px";
    }
}

去浏览器中试验一下,有着很明显的不舒服的地方,也不能算bug,就是用户体验不好,每次按下标题中任一个区域拖动面板,鼠标总会自动跑到整个面板的左上角。这是因为对整个面板的绝对定位是按照左上角那个点进行定位的,也就是说鼠标移动到哪里,最后是面板的左上角跟随到哪里。这显然不是我们想要的,我们需要的是在标题中任一区域按下,鼠标移动到哪里,之前按下的地方就出现在哪里。

我们知道了问题所在,那么该如何解决呢?之前是因为默认的面板左上角跟随鼠标,那我们让按下的地方跟随鼠标不就好了嘛,所有现在就得确定我们在title 区域中按下的位置的坐标。通过一幅图来形象的了解。

整个外框就相当于浏览器边框,红色的点就是我们鼠标按下的位置,那这个点相对于QQ面板的位置信息可以通过clientX/Y - offsetLeft/Top 计算得到。这样的话,之前写的fnDown函数就不对了呀,修改如下。其中,将鼠标移动事件封装成函数。

function fnDown(event){
    event = event || window.event;
    var oDrag=document.getElementById('loginPanel'),
        // 光标按下时光标和面板之间的距离
        disX=event.clientX-oDrag.offsetLeft,
        disY=event.clientY-oDrag.offsetTop;
    // 移动
    document.onmousemove=function(event){
        event = event || window.event;
        fnMove(event,disX,disY);
    }
}

fnMove函数接受三个参数,事件对象,鼠标点击下相对于面板的上左距离。我们是知道鼠标移动后是面板的左上角跟随鼠标,现在已经有了鼠标点击下相对于面板的上左距离的值,那么就可以在原有的左上角坐标增加或减去这个值,这就能够实现鼠标在哪里按下,移动之后就在哪里出现。表述能力真的欠佳,感觉说的乱绕绕的,还是代码清晰。

function fnMove(e,posX,posY){
    var oDrag=document.getElementById('loginPanel'),
        l=e.clientX-posX,
        t=e.clientY-posY,
    oDrag.style.left=l+'px';
    oDrag.style.top=t+'px';
}

以上就很好的解决了之前那个用户体验不好的地方。那会不会还存在一些问题?显而易见,一定会有的。我们拖动面板,有时候在浏览器边界时候会一部分移出可视窗口,这也很糟糕呀,譬如一不小心把关闭按钮啊、登录按钮啊、输入框啊这些部分移除可视窗口,就很不好操作了,还需要用户再把面板移回来,用户体验绝对是不好的。这时就需要我们来设置一个范围,来规定面板可移动的区域。这个区域很明显就是可视窗口的大小减去面板的大小,这剩下的区域就是面板能够尽情移动的范围了。我们需要在fnMove函数基础上增添。

function fnMove(e,posX,posY){
    var oDrag=document.getElementById('loginPanel'),
        l=e.clientX-posX,
        t=e.clientY-posY,
        winW=document.documentElement.clientWidth || document.body.clientWidth, //可视窗口的宽
        winH=document.documentElement.clientHeight || document.body.clientHeight,   //可视窗口的高
        maxW=winW-oDrag.offsetWidth, //可移动的范围的宽
        maxH=winH-oDrag.offsetHeight;   //可移动的范围的高
    if(l<0){
        l=0;
    }else if(l>maxW){
        l=maxW;
    }
    if(t<0){
        t=10;
    }else if(t>maxH){
        t=maxH;
    }
    oDrag.style.left=l+'px';
    oDrag.style.top=t+'px';
}

现在就完成了鼠标移动拖曳的效果,鼠标按下之后就可以拖动面板跟着鼠标移动,嗯,一直移动不带停的。我们必须要有一个鼠标释放的事件,来停止当前的动作。这就用到了onmouseup事件,这个事件的发生是处于整个文档中的。所谓停止当前的动作就是要卸载之前鼠标移动事件,也要卸载当前这个鼠标释放事件。当然这是发生在fnDown函数中。

document.onmouseup=function(){
    document.onmousemove=null;
    document.onmouseup=null;
}

就此,完美的实现了拖曳效果。需要注意的是关于浏览器中坐标的计算。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值