js实现元素的拖拽问题及分类练习汇总

这篇博客详细讲解了JavaScript实现元素拖拽的原理和实践,包括元素在限制范围内的拖动、拖动练习以及碰撞检测。通过理解offsetLeft和offsetTop属性,结合鼠标事件,实现元素任意位置及限制范围内的移动。同时介绍了getBoundingClientRect()用于检测元素碰撞的辅助知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     js高阶之-元素在限制范围内的拖动

一.补充知识

    元素的offsetLeft

              offsetTop

offsetLeft 和 offsetTop 属性返回当前元素的偏移位置。IE 怪异模式以父元素为参照进行偏移位置,DOM 标准模式以最近定位元素为参照进行偏移的位置,offsetLeft是离其最近的已经定位的元素,如果没有就相对于body元素计算

   对应最近父元素情况

   1.body元素

         2.table,th,tr,th元素,但其应具有position:releative\absolute,fixed

   3.除position:static的定位元素

 

二.元素的拖动---任意位置

     拖放的三个事情  

        鼠标落下,锁定了鼠标与元素的相对位置

    

             disX=event.pageX-oDiv.offsetLeft;

            disY=event.pageY-oDiv.offsetTop;

        鼠标移动时,鼠标改变,元素同时改变位置(反推过程)

            

                oDiv.style.left=event.pageX-disX+

                oDiv.style.top=event.pageY-disY+

        鼠标抬起,解除上面的效果

               document.οnmοusemοve=document.οnmοuseup=null;//取消移动效果

实现源码:

  var oDiv=document.querySelector("div");
        oDiv.onmousedown=function(){
            //鼠标距离元素的位置
            var disX=event.pageX-oDiv.offsetLeft;//元素距离页面
            var disY=event.pageY-oDiv.offsetTop;
            document.onmousemove=function(){//换成document---防止位置拖放扔掉现象
                //反推
                oDiv.style.left=event.pageX-disX+"px";
                oDiv.style.top=event.pageY-disY+"px";
            }
            document.onmouseup=function(){
                document.onmousemove=document.onmouseup=null;//取消移动效果
                
            }
            stopDefault(event);
        }

//阻止浏览器默认行为函数封装
function stopDefault( e ) {  //封装函数,该处的event应该为外面传进来的---阻止浏览器默认行为
    if ( e && e.preventDefault ){ //如果存在preventDefault,则这是一个非IE浏览器 
        e.preventDefault();  //阻止默认浏览器动作(W3C) 
    }else {
        window.event.returnValue = false; //IE中阻止函数器默认动作的方式 
    }
}

三.元素在限制范围内的拖拽

  1.布局效果

 <div class="parent">
        <div class="child"></div>
    </div>

 2.CSS样式设置

 <style>
        .parent{
            width: 500px;
            height: 300px;
            position: relative;
            background-color: red;
            margin: 0 auto;
        }
        .child{
            position: absolute;
            left: 0;
            top: 0;
            width: 150px;
            height: 150px;
            background-color: yellow;
        }
    </style>

3.1锁定子元素相对父元素的位置

  myjs.js库里的函数offsetWindow(obj)---获取元素相对页面的位置  

     var ochoff= offsetWindow(this);---子元素

      var disX=event.pageX-ochoff[0];

      var disY=event.pageY-ochoff[1];

获取子元素到父元素的相对位置(将来要到达的位置)

          var oPaoff= offsetWindow(oPar);

          var willLeft=event.pageX-disX-oPaoff[0];

          var willTop=event.pageY-disY-oPaoff[1];

3.2锁定边界位置

将来要到达的左上位置要大于0且小于右,下边界

         willLeft=Math.max(willLeft,0);

          willTop=Math.max(willTop,0);

                     右下

父元素宽度-子元素宽度=所能拖动的最大距离

          willLeft=Math.min(oPar.offsetWidth-oCh.offsetWidth,willLeft);

          willTop=Math.min(oPar.offsetHeight-oCh.offsetHeight,willTop);

4.源码

<script>
    var oPar=document.querySelector(".parent");
    var oCh=document.querySelector(".child");
    oCh.onmousedown=function(){
        // 鼠标相对元素的位置
      var ochoff= offsetWindow(this);
      var disX=event.pageX-ochoff[0];
      var disY=event.pageY-ochoff[1];
      document.onmousemove=function(){
        var oPaoff= offsetWindow(oPar);
//子元素相对父元素的位置
          var willLeft=event.pageX-disX-oPaoff[0];
          var willTop=event.pageY-disY-oPaoff[1];
//锁定边界
          willLeft=Math.max(willLeft,0);
          willTop=Math.max(willTop,0);
          willLeft=Math.min(oPar.offsetWidth-oCh.offsetWidth,willLeft);
          willTop=Math.min(oPar.offsetHeight-oCh.offsetHeight,willTop);
          oCh.style.left=willLeft+"px";
          oCh.style.top=willTop+"px";
      }
      document.onmouseup=function(){
                document.onmousemove=document.onmouseup=null;//取消移动效果
                
            }
            stopDefault(event);//文字内容或产生 新页面
    }
</script>

 

四.元素拖动练习1

                *大图拖放永远不出现留白

唯一不同点:边界大小互换

          willLeft=Math.min(willLeft,0);

          willTop=Math.min(willTop,0);

          willLeft=Math.max(oDiv.offsetWidth-oImg.offsetWidth,willLeft);

          willTop=Math.max(oDiv.offsetHeight-oImg.offsetHeight,willTop);

源码:

<style>
        div{
            width: 1080px;
            height: 535px;
            background-color: red;
            border: 1px black solid;
            margin: 50px auto;
            overflow: hidden;
            position: relative;
        }
        img{
        position: absolute;
        left: 0;
        top: 0;
        }
    </style>
</head>
<body>
    <div>
        <img src="移动图片.jpg" alt="">
    </div>
</body>
<script src="myJs.js"></script>
<script>
    var oDiv=document.querySelector("div");
    var oImg=document.querySelector("img");
    oImg.onmousedown=function(){
        var Ioff= offsetWindow(this);
      var disX=event.pageX-Ioff[0];
      var disY=event.pageY-Ioff[1];
      document.onmousemove=function(){
        var Doff= offsetWindow(oDiv);
//边界设置
          var willLeft=event.pageX-disX-Doff[0];
          var willTop=event.pageY-disY-Doff[1];
//大小互换卡边界
          willLeft=Math.min(willLeft,0);
          willTop=Math.min(willTop,0);
          willLeft=Math.max(oDiv.offsetWidth-oImg.offsetWidth,willLeft);
          willTop=Math.max(oDiv.offsetHeight-oImg.offsetHeight,willTop);
          oImg.style.left=willLeft+"px";
          oImg.style.top=willTop+"px";
      }
    //   取消默认情况
      document.onmouseup=function(){
                document.onmousemove=document.onmouseup=null;//取消移动效果
                
            }
            stopDefault(event);//文字内容或产生 新页面
    }
</script>

 

 

五.元素的拖动练习2

                 *自制滚动条效果

   1.布局

<body>
    <div class="wrap">
        <div class="line"></div>
    </div>
    <div class="box"></div>
</body>

  2.CSS样式

  .wrap{
            width: 20px;
            height: 400px;
            background-color: #cccccc;
            position: absolute;
            left: 200px;
            top: 200px;
        }
        .line{
            width: 20px;
            height: 50px;
            background-color: blue;
            position: absolute;
            left: 0px;
            top: 0px;
        }

3.JS源码

var oLoff=offsetWindow(this);
var disY=event.pageY-oLoff[1];

document.onmousemove=function(){
    var oWoff=offsetWindow(oW);
    var willTop=event.pageY-disY-oWoff[1];
    // 限制
    willTop=Math.max(willTop,0);
    willTop=Math.min(oW.offsetHeight-oL.offsetHeight,willTop);
oL.style.top=willTop+"px";
}
//取消设置
document.onmouseup=function(){
    document.onmousemove=document.onmouseup=null;
}
stopDefault(event);
    }

六.检测碰撞

补充知识:         getBoundingClientRect()一个对象的大小和相对页面的位置

源码:

  <title>Document</title>
    <style>
        .mubiao{
            width: 200px;
            height: 200px;
            background-color: blue;
            margin: 0 auto;
        }
        .tuofang{
       width: 150px;
       height: 150px;
       position: absolute;
       left: 0;
        top: 0;
       background-color: red;
        }
    </style>
</head>
<body>
    <div class="tuofang"></div>
    <div class="mubiao"></div>
</body>
<script src="myJs.js"></script>
<script>
    var rectObject=document.getElementsByTagName("div")[0].getBoundingClientRect();
    var oTF=document.querySelector(".tuofang");
    var oMB=document.querySelector(".mubiao");
    oTF.onmousedown=function(){
      //获取鼠标相对元素相对位置
        var disX=event.pageX-oTF.offsetLeft;
        var disY=event.pageY-oTF.offsetTop;
        document.onmousemove=function(){
            var Wl=event.pageX-disX;
            var wt=event.pageY-disY;
            var oTFrect=oTF.getBoundingClientRect();
            var oMBrect=oMB.getBoundingClientRect();
//判断八块位置
            if(oMBrect.left>=oTFrect.right||oMBrect.top>=oTFrect.bottom||oTFrect.left>=oMBrect.right||oMBrect.bottom<=oTFrect.top){
                console.log("未撞上");
                oMB.style.backgroundColor="blue";
                
            }else{
                console.log("撞上了");
                oMB.style.backgroundColor="yellow";
            }
            oTF.style.left=Wl+"px";
            oTF.style.top=wt+"px";
        }
//清除原设置效果
        document.onmouseup=function()
    {
        document.onmousemove=document.onmouseup=null;
        }
        stopDefault(event);
    }
</script>

         元素拖放所有复习问题,图文均为自己制作,不允许转载@毛毛同学

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值