使用js中常用的鼠标事件实现一个拖拽的例子

一、js中常用的几个必备鼠标事件

  • onclick: 元素上发生鼠标点击时触发.
  • ondblclick: 元素上发生鼠标双击时触发.
  • onmousedown: 当元素上按下鼠标按钮时触发.
  • onmouseup: 当在元素上释放鼠标按钮时触发.
  • onmouseout: 当鼠标指针移出元素时触发.
  • onmousemove: 当鼠标指针移动到元素上时触发.
  • onmouseover: 当鼠标指针移动到元素上时触发.

这里来说一下move和over的区别:over是鼠标指针在刚进入该元素的时候就触发,在鼠标在该元素上移动过程中不在改变状态;move是只要鼠标指针在该元素的上面移动就触发,在鼠标在该元素上移动过程中状态一直在变化,比如坐标就在一直改变,多数情况下用over就可以了。

二、使用一个例子来实现拖拽效果

html结构代码
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>拖动</title>
    <link href="css/main.css" rel="stylesheet" />
    <script src="js/drag.js"></script>
</head>
<body>
    <div class="loginPanel" id="loginPanel">
         <div style="position: relative; z-index: 1;">
            <div class="ui_boxyClose" id="ui_boxyClose"></div>
        </div>
        <div class="login_logo_webqq"></div>
        <div class="inputs">
            <div class="sign-input"><span>帐 号:</span><span><input autocomplete="on" name="u" id="u" type="text" style="ime-mode: disabled" class="input01" tabindex="1" value="QQ号码或Email帐号" onFocus="if (value =='QQ号码或Email帐号'){value =''}" onBlur="if (value ==''){value='QQ号码或Email帐号';}" /></span></div>
            <div class="sign-input"><span>密 码:</span><span><input name="p" id="p" maxlength="16" type="password" class="input01" tabindex="2" /></span></div>
        </div>

        <div class="bottomDiv">
            <div class="btn" style="float: left"></div>
            <div>
                <div id="loginState" class="login-state-trigger login-state-trigger2 login-state" title="选择在线状态">
                    <div id="loginStateShow" class="login-state-show online">状态</div>
                    <div class="login-state-down">下</div>
                    <div class="login-state-txt" id="login2qq_state_txt">在线</div>
       <ul id="loginStatePanel" class="statePanel login-state" style="display: none">
        <li id="online" class="statePanel_li">
            <div class="stateSelect_icon online"></div>
            <div class="stateSelect_text">我在线上</div>
        </li>
        <li id="callme" class="statePanel_li">
            <div class="stateSelect_icon callme"></div>
            <div class="stateSelect_text">Q我吧</div>
        </li>
        <li id="away" class="statePanel_li">
            <div class="stateSelect_icon away"></div>
            <div class="stateSelect_text">离开</div>
        </li>
        <li id="busy" class="statePanel_li">
            <div class="stateSelect_icon busy"></div>
            <div class="stateSelect_text">忙碌</div>
        </li>
        <li id="silent" class="statePanel_li">
            <div class="stateSelect_icon silent"></div>
            <div class="stateSelect_text">请勿打扰</div>
        </li>
        <li id="hidden" class="statePanel_li">
            <div class="stateSelect_icon hidden"></div>
            <div class="stateSelect_text">隐身</div>
        </li>
    </ul>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

上面是html结构代码,不是重点不详细说,此外,由于css代码和其他图片资源太多不给出了,我的重点是梳理一下怎么实现这个面板的拖拽。
使用class分析结构:
loginPanel:整个面板。
ui_boxyClose:右上角的关闭按钮。
login_logo_webqq:标题区域。
inputs:用户名和密码。
bottomDiv:图标显示qq状态区域。

下面是拖拽的js代码的实现:

//因为html中基本都是使用的class所以我们封装一个使用类名取出元素的方法。getElementsByClassName()在ie10一下都不能用,所以我们自己封装。
function getByClass(clsname,parent){
  var par,arr,eles=[];
  if(parent){
    par=document.getElementById(parent);
  }else{
    par=document;
  }
  arr=par.getElementsByTagName('*');
  //console.log(arr);
  for(var i=0;i<arr.length;i++){
    if(arr[i].className==clsname){
      eles.push(arr[i]);
    }
  } 
  //console.log(eles);
  return eles;
}
window.onload=function(){
  getByClass("login_logo_webqq","loginPanel");
}

接着我们来进行拖拽功能的实现:我们想要实现地是当用户在标题区域login_logo_webqq按下鼠标不释放的在页面拖动时候面板跟着移动的效果。
在这里说一下面板要想被拖动的条件:任何能够跟着鼠标移动的东西 都要有一个前提:绝对定位。所以面板必须被绝对定位。还有拖动的意思其实就是面板跟着光标走,光标去哪里,面板就去哪里,所以我们就可以简单的按照下面实现:

indow.onload=drag;
function drag(){
  //获取鼠标被按住就能被拖动的区域:标题
  var title= getByClass("login_logo_webqq","loginPanel")[0];
  //console.log(title);
  //给标题区域加上按下鼠标事件
  title.onmousedown=fdown;
}
function fdown(){
  //希望面板跟着光标走,下面需要获得面板
  var panel=document.getElementById("loginPanel");
  console.log(panel);
  //当按下鼠标就应该加上在元素内部移动的事件了也就是move,因为是在整个页面移动所以是document
  document.onmousemove=function(event){
     event = event || window.event;
     panel.style.left=event.clientX +'px';
     panel.style.top=event.clientY +'px';
  }  

}

这是最简单的情况,但是我们发现这样写是有错的,就是当我们在标题区域按下鼠标打算移动的时候,那个鼠标都会跑到左上角去,其实这是正常的,因为计算坐标值的时候都是用左上角作为参考,那怎么让鼠标留在原位置不跑去左上角呢? 那我们的鼠标的left, top需要在原来左上角的位置右移,下移。那面板需要左移上移。所以鼠标的left, top在原来的基础上减去一个按下鼠标的位置相对面板的left,top.所以重点是求按下鼠标的位置相对面板的left,top。这也很好求是鼠标的坐标-面板相对浏览器的left,top.

window.onload=drag;
function drag(){
  //获取鼠标被按住就能被拖动的区域:标题
  var title= getByClass("login_logo_webqq","loginPanel")[0];
  //console.log(title);
  //给标题区域加上按下鼠标事件
  title.onmousedown=fdown;
}
//fdown的event是鼠标按下的事件
function fdown(event){
  //希望面板跟着光标走,下面需要获得面板
  var panel=document.getElementById("loginPanel");
  //console.log(panel);
  //光标按下时,光标和面板的相对距离
  event = event || window.event;
  var reX=event.clientX-panel.offsetLeft;
  var reY=event.clientY-panel.offsetTop;
  console.log(reX);
  //当按下鼠标就应该加上在元素内部移动的事件了也就是move,因为是在整个页面移动所以是document
  //这里的event是面板移动时候的事件
  document.onmousemove=function(event){
     event = event || window.event;
     panel.style.left=(event.clientX-reX) +'px';
     panel.style.top=(event.clientY-reY) +'px';
  }  

}

最后一个不足就是拖拽过程中,不能出去屏幕,我们可以这样解决:
我们水平的left的范围:0到(浏览器宽度-面板宽度)
我们垂直的top的范围:0到(浏览器高度-面板高度)
这里还有一点需要特别注意,那就是样式表里面有没有top,left的设置,如果有会影响到left的范围,我们这里就有,这样的话需要先把css中设置的top,left先处理掉。

window.onload=drag;
function drag(){
  //获取鼠标被按住就能被拖动的区域:标题
  var title= getByClass("login_logo_webqq","loginPanel")[0];
  //console.log(title);
  //给标题区域加上按下鼠标事件
  title.onmousedown=fdown;

}
//fdown的event是鼠标按下的事件
function fdown(event){
  //希望面板跟着光标走,下面需要获得面板
  var panel=document.getElementById("loginPanel");
  //console.log(panel);
  //光标按下时,光标和面板的相对距离
  event = event || window.event;
  var reX=event.clientX-panel.offsetLeft;
  var reY=event.clientY-panel.offsetTop;
  //console.log(reX);
  //当按下鼠标就应该加上在元素内部移动的事件了也就是move,因为是在整个页面移动所以是document
  //这里的event是面板移动时候的事件
  //获得left和top的最大值
  var MX=(document.documentElement.clientWidth || document.body.clientWidth)-panel.offsetWidth;
  var MY=(document.documentElement.clientHeight || document.body.clientHeight)-panel.offsetHeight;
  console.log(MX);
  document.onmousemove=function(event){
     event = event || window.event;
     var X=event.clientX-reX;
     var Y=event.clientY-reY;
     if(X<0){
      X=0;
     }else if(X>MX){
       X=MX;
     }
     if(Y<0){
      Y=0;
     }else if(Y>MY){
       Y=MY;
     }
     panel.style.left=X +'px';
     panel.style.top=Y +'px';
  }  
   // 释放鼠标
  document.onmouseup=function(){
    document.onmousemove=null;
  }

}
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现前端对某一个图片进行随意拖拽,可以通过以下步骤实现: 1. 给图片添加鼠标按下、鼠标移动鼠标松开事件的监听器。 2. 在鼠标按下事件记录下鼠标相对于图片左上角的坐标(即鼠标落点与图片左上角之间的距离)。 3. 在鼠标移动事件计算出鼠标当前的坐标,并将图片的位置设置为鼠标当前坐标减去鼠标落点与图片左上角之间的距离。 4. 在鼠标松开事件取消对鼠标移动事件的监听。 下面是一个简单的示例代码: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>拖拽图片</title> <style> #image { position: absolute; left: 0; top: 0; cursor: move; } </style> </head> <body> <img src="image.jpg" id="image" width="200" height="200"> <script> var image = document.getElementById('image'); var offsetX, offsetY; var isDragging = false; image.addEventListener('mousedown', function (event) { offsetX = event.clientX - image.offsetLeft; offsetY = event.clientY - image.offsetTop; isDragging = true; }); document.addEventListener('mousemove', function (event) { if (isDragging) { image.style.left = event.clientX - offsetX + 'px'; image.style.top = event.clientY - offsetY + 'px'; } }); document.addEventListener('mouseup', function () { isDragging = false; }); </script> </body> </html> ``` 在这个例子,我们给图片设置了一个 `id` 为 `image`,并且使用了绝对定位(`position: absolute`),使得图片可以在父元素随意拖拽。我们在 CSS 还设置了 `cursor: move`,使得鼠标在图片上时显示为移动光标。 在 JavaScript ,我们首先获取了图片元素和鼠标按下时的偏移量 `offsetX` 和 `offsetY`,在鼠标移动事件计算出当前鼠标的坐标,并将图片的位置设置为鼠标的坐标减去偏移量。在鼠标松开事件,我们将 `isDragging` 标记为 `false`,表示图片已经停止拖拽

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值