整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

JavaScript 如何拖拽元素-

JavaScript 如何拖拽元素?

例: 限制范围的拖拽

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.box{
width: 800px;
height: 400px;
margin: 50px auto;
border: 1px solid #f00;
/*让拖拽元素根据它进行定位*/
position: relative;
}
.move{
width: 200px;
height: 120px;
cursor: move;
background-color: orange;
/*定位属性*/
position: absolute;
left: 100px;
top: 50px;
}
</style>
</head>
<body>
<div class="box">
<div class="move"></div>
</div>

<script type="text/javascript">
    //获取box盒子
    var box=document.querySelector(".box");
    //获取拖拽的盒子
    var move=document.querySelector(".move");
    //求得box盒子距离body的净位置
    var boxLeft=box.getBoundingClientRect().left;
    var boxTop=box.getBoundingClientRect().top;
    //拖拽三大事件
    move.onmousedown=function(e){
    var ev=e || window.event;//事件对象兼容
    //存储鼠标按下时到事件源的位置
    var startX=ev.offsetX;
    var startY=ev.offsetY;


    document.onmousemove=function(e){
    var ev=e || window.event;//事件对象兼容
    //真实的拖拽元素的left和top值
    var left=ev.clientX -boxLeft - startX;
    var top=ev.clientY - boxTop - startY;
    //多拖拽盒子的left和top值进行约束
    if(left<0){
    left=0;//left最小是0
    }else if(left>(box.offsetWidth-move.offsetWidth)){
    left=box.offsetWidth-move.offsetWidth;//left最大是大盒子宽度-小盒子宽度
    }
    if(top<0){
    top=0;//top最小是0
    }else if(top>(box.offsetHeight-move.offsetHeight)){
    top=box.offsetHeight-move.offsetHeight;//top最大是大盒子高度-小盒子高度
    }


    //设置拖拽元素的left和top属性值
    move.style.left=left + "px"
    move.style.top=top + "px"
    }
    document.onmouseup=function(){
    document.onmousemove=null;
    document.onmouseup=null;
    }
    }
</script>
</body>
</html>

实例: 进一步优化(带吸附拖拽)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.box{
width: 800px;
height: 400px;
margin: 50px auto;
border: 1px solid #f00;
/*让拖拽元素根据它进行定位*/
position: relative;
}
.move{
width: 200px;
height: 120px;
cursor: move;
background-color: orange;
/*定位属性*/
position: absolute;
left: 100px;
top: 50px;
}
</style>
</head>
<body>
<div class="box">
<div class="move"></div>
</div>

<script type="text/javascript">
    //获取box盒子
    var box=document.querySelector(".box");
    //获取拖拽的盒子
    var move=document.querySelector(".move");
    //求得box盒子距离body的净位置
    var boxLeft=box.getBoundingClientRect().left;
    var boxTop=box.getBoundingClientRect().top;
    //拖拽三大事件
    move.onmousedown=function(e){
    var ev=e || window.event;//事件对象兼容
    //存储鼠标按下时到事件源的位置
    var startX=ev.offsetX;
    var startY=ev.offsetY;


    document.onmousemove=function(e){
    var ev=e || window.event;//事件对象兼容
    //真实的拖拽元素的left和top值
    var left=ev.clientX -boxLeft - startX;
    var top=ev.clientY - boxTop - startY;
    //弹性吸附 就是让他还差**px时我就让他到边边上
    if(left<20){
    left=0;//left最小是0
    }else if(left>(box.offsetWidth-move.offsetWidth-20)){
    left=box.offsetWidth-move.offsetWidth;//left最大是大盒子宽度-小盒子宽度
    }
    if(top<20){
    top=0;//top最小是0
    }else if(top>(box.offsetHeight-move.offsetHeight-20)){
    top=box.offsetHeight-move.offsetHeight;//top最大是大盒子高度-小盒子高度
    }


    //设置拖拽元素的left和top属性值
    move.style.left=left + "px"
    move.style.top=top + "px"
    }
    document.onmouseup=function(){
    document.onmousemove=null;
    document.onmouseup=null;
    }
    }
</script>
</body>
</html>

实例: 进一步优化(带影子拖拽)

节我们学习 HTML5 中的拖放,拖放是一种常见的特性,也就是抓取对象以后拖到另一个位置。在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放。

拖放事件

拖放是由拖动与释放两部分组成,拖放事件也分为被拖动元素的相关事件,和容器的相关事件。

被拖动元素的相关事件如下所示:



容器相关事件如下所示:



如何实现元素的拖放

我们通过上述的拖放事件来实现将下图“你好,侠课岛”,拖放到上面的矩形框中的演示效果:


  • 首先创建一个HTML文本,用于测试代码,如下所示:
<!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>HTML5学习(9xkd.com)</title>
            <style type="text/css">
                .div1{
                    width:200px;
                    height:100px;
                    padding:20px;
                    border:1px solid #000;
                }
                p{
                    font-size: 28px;
                }
            </style>
        </head>
        <body>
            <div>
                <div class="div1" id="div1" ></div>
                <p id="drag1">你好,侠课岛!</p>
            </div>
        </body>
    </html>
  • 然后,我们要给被拖动元素(也就是在上述的 <p> 标签上),设置一个 draggable 属性,此属性用于规定元素是否可拖动,当属性值为 true 时表示元素可拖动,为 false 表示元素不可拖动。
<p id="drag1" draggable="true">你好,侠课岛!</p>

只有设置了 draggable 属性值为 true ,指定元素才能被拖动。

  • 然后,我们要做的是点击被拖动元素 “你好,侠课岛!”,点击这个元素时需要触发一个 ondragstart 事件,ondragstart 事件会在用户开始拖动元素或选择的文本时触发。调用了一个 drag(event) 函数,在这个函数中规定被拖动的数据,如下所示:
function drag(e){
    e.dataTransfer.setData("Text", e.target.id);
}

代码中的 dataTransfer.setData() 方法用于设置被拖数据的数据类型和值。参数 Text 表示被拖动数据的数据类型,参数 e.target.id 是可拖动元素的 id。

  • 接着,我们将要 “你好,侠课岛!” 拖动到元素容器范围内(矩形框中)。要实现这个步骤,需要在放置拖动元素的容器上绑定一个 ondragover 事件,这个事件用于规定在何处放置被拖动的数据。默认情况下,是无法将一格元素放置到另外一个元素里面的,所以如果需要设置允许放置,则要在 ondragover 事件中加上 e.preventDefault() 方法来阻止默认行为。
function allowDrop(e){
    e.preventDefault();
}
  • 最后,就是要放置被拖动元素,也就是要在元素容器范围内松开鼠标。需要在元素容器上绑定一个 ondrop 事件,如下所示,这个事件会在拖动过程中释放鼠标键时触发。
<div id="div1" class="div1" ondrop="drop(event)" ondragover="allowDrop(event)" ></div>

<script>
    function drop(e){
        e.preventDefault();
        var data=e.dataTransfer.getData("Text");
        e.target.appendChild(document.getElementById(data));
    }
</script>

在 ondrop 事件中同样需要调用 e.preventDefault() 方法来阻止默认行为。然后可以通过 dataTransfer.getData("Text"); 方法获取之前的 drag(event) 函数中保存的信息,也就是被拖动元素的 id。接着通过 target.appendChild() 方法为将拖动元素作为元素容器的子元素追加到元素容器中,这样就能成功实现拖放。

完整代码

完整代码如下所示:

<!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>HTML5学习(9xkd.com)</title>
            <style type="text/css">
                .div1{
                    width:200px;
                    height:100px;
                    padding:20px;
                    border:1px solid #000;
                }
                p{
                    font-size: 28px;
                }
            </style>
        </head>
        <body>
            <div>
                <div id="div1" class="div1" ondrop="drop(event)" ondragover="allowDrop(event)" ></div>
                <p id="drag1" draggable="true" ondragstart="drag(event)">你好,侠课岛!</p>
            </div>
            <script>
                function drag(e){
                    e.dataTransfer.setData("Text", e.target.id);
                }
                function allowDrop(e){
                    e.preventDefault();
                }
                function drop(e){
                    e.preventDefault();
                    var data=e.dataTransfer.getData("Text");
                    e.target.appendChild(document.getElementById(data));
                }
            </script>
        </body>
    </html>

总结

当我们要对某个元素实行拖放操作时,首先就需将这个元素的 draggable 属性设置为 true,表示允许元素拖动。其中图片和链接默认是可拖动的,不需设置要 draggable 属性。

链接:https://www.9xkd.com/

拽成为一项标准也是近几年的事,属于HTML5中的一部分,作为一种交互行为,拖拽是被广泛应用再界面软件中的,例如桌面应用,word、QQ软件都有拖拽行为。

在HTML5标准实施之前,拖拽也是被广泛使用的,web开发者将click、mouseover,mousemove组合起来实现拖拽逻辑,过程略显冗余和繁琐。

一言蔽之,HTML5的出现让拖拽开发变得简单

先来一张流程图

下图描绘了拖拽的流程.

要点概括总结

结合上图,我们梳理下知识点,做个拆分与解析。

一共有哪些事件

  • 拖: dragstart , drag , dragend
  • 放: dragenter , dragover , dragleave , drop

哪些实体可以被拖

draggable
wordContainerEle.onselectstart=event=> false;

这意味着:

  • 元素 默认禁止拖拽 (貌似都是),需要手动设置draggable属性为true。
  • 文字默认都是能选中的,这个大家都习以为常了。

需要说明的是,一个元素被设置draggable之后,里面的文本就无法被选中了(chrome测试如此)。

关于放,有哪些限制?

  • dragenter :都可以。
  • dragover :都可以
  • dragleave :都可以
  • drop :只有在 dragover监听中阻止默认行为 ,才能触发drop

拖放会冒泡嘛?

答案是肯定的。假设一个父元素包含一个子元素,理所当然地,用户拖子元素也是间接的拖动父元素的过程。