zoukankan      html  css  js  c++  java
  • 基本拖拽和拖拽衍生的问题

    1、拖拽的原理

    主要是用了三个鼠标事件,onmousedown、onmousemove、onmouseup。当鼠标按下时,计算出鼠标距离拖拽物体border的距离,假设拖拽物体是一个100*100px的小块,在鼠标按下时再检测鼠标移动后鼠标的位置,用当前鼠标的位置去减去鼠标距离拖拽物体border的距离,把作差的结果赋给div的left和top,这样就达到拖拽的目的,当然当鼠标释放时,还是把onmousemove、onmousedown事件清除,已达到拖拽完鼠标释放的目的。这就是简单的拖拽原理。也是最实用的。

    下面是源码:

      <!DOCTYPE html>
      <html>
      <head lang="en">
          <meta charset="UTF-8">
          <title></title>
      </head>
      <style>
          #div1{100px;  height: 100px;  background-color: red; position: absolute}
      </style>
     <script>
         window.onload=function(){
             var oDiv=document.getElementById(id);
             oDiv.onmousedown=function(ev){
                 oEvent=ev||event;
                 //鼠标距离小块border的距离
                 var disX=oEvent.clientX-oDiv.offsetLeft;
                 var disY=oEvent.clientY-oDiv.offsetTop;
                 document.onmousemove=function(ev){
                     oEvent=ev||event;
                     //移动后,想要移动的距离
                     var l=oEvent.clientX-disX;
                     var t=oEvent.clientY-disY;
                     //把l和t赋值给div的left和top让其达到运动的效果
                     oDiv.style.left=l+'px';
                     oDiv.style.top=t+'px';
                 };
                 document.onmouseup=function(){
                     //鼠标释放后,把事件清空
                     document.onmousedown=null;
                     document.onmousemove=null
                }
             }
         }
     </script>
     <body>
     <div id="div1"></div>
    </body>
    </html>
    为什么要把onmousemove事件加到onmousedown事件里面?  防止抖动
    为什么要document.onmousemove  因为document足够大

    在这里不得不说下,style.width/height和offsetLeft/Top的区别,下面是以width举例的,height也类似

    offsetWidth属性可以返回对象的padding+border+width属性值之和
    offsetWidth属性仅是可读属性,而style.width是可读写的。
    offsetWidth属性返回值是整数,而style.width的返回值是字符串。
    style.width仅能返回以行内方式定义的内部样式表的width属性值
    2、有限制范围的拖拽
    其实有限制范围的拖拽很简单,就是判断l和t的取值范围
    代码如下:
                     if(l<0)
                    {
                        l=0;
                    }
                    else if(l>document.documentElement.clientWidth-oDiv.offsetWidth)
                    {
                        l=document.documentElement.clientWidth-oDiv.offsetWidth;
                    }
                    if(t<){
                        t=0;
                    }
                    else if(t>document.documentElement.clientHeight-oDiv.offsetHeight){
                        t=document.documentElement.clientHeight-oDiv.offsetHeight
                    }            

    document.documentElement.clientWidth就是当前网页窗口的宽度,如果调整了网页宽口的宽度,document.documentElement.clientWidth也会根据你调整后变化。

    document.documentElement.clientHeight也类似

    下面附一张图来解释原理

    left和top容易理解,right和bottom是这样的,上图 a=offsetLeft b=document.documentElement.clientWidth c=小块宽度,当a>b-c时说明小块出去了,这时候把l=document.documentElement.clientWidth-oDiv.offsetWidth。height同理,这样就达到了不让小块出界的目的

    3、磁性吸附

    磁性吸附就是小块快到上下左右边界时,让小块立马贴近边界,达到吸附的目的

    代码如下:

       if(l<50)
                    {
                        l=0;
                    }
                    else if(l>document.documentElement.clientWidth-oDiv.offsetWidth-50)
                    {
                        l=document.documentElement.clientWidth-oDiv.offsetWidth;
                    }
                    if(t<50){
                        t=0;
                    }
                    else if(t>document.documentElement.clientHeight-oDiv.offsetHeight-50){
                        t=document.documentElement.clientHeight-oDiv.offsetHeight
                    }

    磁性吸附其实和限制小块范围的原理类似,当l还有50px小于0,这时候把l等于0,以至于在l<50范围内,都让l=0; 当l>document.documentElement.clientWidth-oDiv.offsetWidth-50时,l=document.documentElement.clientWidth-oDiv.offsetWidth让小块立即贴近页面右边框。

    如上图,当小块向右距离小于50px 都是l>document.documentElement.clientWidth-oDiv.offsetWidth-50,把其l=document.documentElement.clientWidth-oDiv.offsetWidth,这样就达成了磁性吸附的目的。

    4、碰撞检测
    碰撞检测的原理很简单,有两个div,div1和div2,在div1可以移动 div2保持不动,div1在div2大小之外,就让其颜色不变,当在div2内,让其颜色改变。

    代码如下:

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <style>
        #div1{width:100px;  height: 100px;  background-color: red; position: absolute;z-index:2;}
        #div2{width:100px;  height: 100px;  background-color: green; position: absolute ;left:300px;top:500px;z-index: 1}
    </style>
    <script>
        window.onload=function(){
            var oDiv=document.getElementById('div1');
            var oDiv2=document.getElementById('div2');
            oDiv.onmousedown=function(ev){
                oEvent=ev||event;
                //移动前的距离window的距离
                var disX=oEvent.clientX-oDiv.offsetLeft;
                var disY=oEvent.clientY-oDiv.offsetTop;
                document.onmousemove=function(ev){
                    oEvent=ev||event;
                    //移动后,想要移动的距离
                    var l=oEvent.clientX-disX;
                    var t=oEvent.clientY-disY;
                    var a=oDiv.offsetLeft;
                    var b=oDiv.offsetHeight+oDiv.offsetLeft;
                    var c=oDiv.offsetTop;
                    var d=oDiv.offsetHeight+oDiv.offsetTop;
    
                    var a2=oDiv2.offsetLeft;
                    var b2=oDiv2.offsetHeight+oDiv2.offsetLeft;
                    var c2=oDiv2.offsetTop;
                    var d2=oDiv2.offsetHeight+oDiv2.offsetTop;
                    if(b<a2||d<c2||c>d2||a>b2){
                        oDiv2.style.background='green'
                    }
                    else{
                        oDiv2.style.background='yellow'
    
                    }
                    //把l和t赋值给div的left和top让其达到运动的效果
                    oDiv.style.left=l+'px';
                    oDiv.style.top=t+'px';
                };
                document.onmouseup=function(){
                    //鼠标释放后,把事件清空
                    document.onmousedown=null;
                    document.onmousemove=null
                }
            }
        };
    
    </script>
    <body>
    <div id="div1"></div>
    <div id="div2"></div>
    </body>
    </html>

     这红圈之外,让其颜色不变,在红圈之内,让其颜色改变。

    if(b<a2||d<c2||c>d2||a>b2){
    oDiv2.style.background='green'
    }
    else{
    oDiv2.style.background='yellow'
    }
     5、拖拽带框,也就是拖拽后有一个拖拽框,在确定拖拽位置后,那个框会消失

    就是要达到上图的效果

    代码如下:

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <style>
        #div1{width:100px;  height: 100px;  background-color: yellow; position: absolute}
        .box{position: absolute;border: dotted 1px black}
    </style>
    <script>
        window.onload=function(){
            var oDiv=document.getElementById('div1');
            var newDiv=document.createElement('div');
            oDiv.onmousedown=function(ev){
                oEvent=ev||event;
                //移动前的距离window的距离
                var disX=oEvent.clientX-oDiv.offsetLeft;
                var disY=oEvent.clientY-oDiv.offsetTop;
                document.onmousemove=function(ev){
                    oEvent=ev||event;
                    //移动后,想要移动的距离
                    var l=oEvent.clientX-disX;
                    var t=oEvent.clientY-disY;
                    newDiv.className='box';
                    newDiv.style.width=oDiv.offsetWidth-2+'px';
                    newDiv.style.height=oDiv.offsetHeight-2+'px';
                    document.body.appendChild(newDiv);
                    oDiv.style.opacity=0.5;
                    //把l和t赋值给div的left和top让其达到运动的效果
                    newDiv.style.left=l+'px';
                    newDiv.style.top=t+'px';
                };
                document.onmouseup=function(){
                    //鼠标释放后,把事件清空
                    document.onmousedown=null;
                    document.onmousemove=null;
                    document.body.removeChild(newDiv);
                    oDiv.style.left=newDiv.style.left;
                    oDiv.style.top=newDiv.style.top;
                    oDiv.style.opacity=1;
                }
            }
        }
    </script>
    <body>
    <div id="div1" ></div>
    </body>
    </html>

    原理就是:当鼠标按下时,创建一个div,当鼠标抬起时,删除新创建的div,注意的一点就是:这时候移动的不是实际小块的位置,而是新建div的位置,让新建div移到某一位置后,再把新建div的left和top赋给小块的left和top,这样就达到边框先移动,移到某一位置后,真实的物体再到这一位置。

      6、利用div改变其父级的大小,就像实现博客园写随笔的的框大小的调整

    代码如下:

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <style>
        #div1{width:10px;  height: 10px;bottom: 0;  right: 0; background-color: red; position: absolute}
        #div2{width:100px;  height: 100px;  background-color: green; position: relative}
    </style>
    <script>
        window.onload=function(){
            var oDiv=document.getElementById('div1');
            var oDiv2=document.getElementById('div2');
            oDiv.onmousedown=function(ev){
                oEvent=ev||event;
                //移动前的距离window的距离
                var disX=oEvent.clientX-oDiv.offsetLeft;
                var disY=oEvent.clientY-oDiv.offsetTop;
                document.onmousemove=function(ev){
                    oEvent=ev||event;
                    //移动后,想要移动的距离
                    var l=oEvent.clientX-disX+oDiv.offsetWidth;
                    var t=oEvent.clientY-disY+oDiv.offsetHeight;
                    //把l和t赋值给div的left和top让其达到运动的效果
                    oDiv2.style.width=l+'px';
                    oDiv2.style.height=t+'px';
                };
                document.onmouseup=function(){
                    //鼠标释放后,把事件清空
                    document.onmousedown=null;
                    document.onmousemove=null
                }
            }
        }
    </script>
    <body>
    <div id="div2"><div id="div1"></div></div>
    </body>
    </html>

    原理:和基本拖拽的唯一区别就是两点,一、父级  position是relative   子集position是absolute,这样保证子集的父级内,bottom:0和right:0让子集在右下角

           二、这时候拖拽改变了不是原物体的位置,而是把拖拽到某一位置的坐标,赋给父级div的宽度,注意:是style.width,它是一个字符串 带'px',height类似,这样就形成了一个改变父级边框大小的效果。

    总结:

    拖拽是常见的一种交互效果,掌握拖拽也对我们熟悉页面结构有很大帮助,下面附一张我珍藏好久的牛x图,了解各种宽高之间的区别


  • 相关阅读:
    DM8168通过GPMC接口与FPGA高速数据通信实现
    2016年 我在浙大计算机学院在职研究生学习经历
    CCS Font 知识整理总结
    Hexo 博客部署到 GitHub
    树莓派配置 USB 无线网卡
    树莓派搭建 Hexo 博客(二)
    树莓派搭建 Hexo 博客(一)
    树莓派初次使用的基本配置.md
    语法测试cnblogs使用Markdown
    硬件工程师-面试笔记0305
  • 原文地址:https://www.cnblogs.com/dirkhe/p/6278809.html
Copyright © 2011-2022 走看看