DOM drag 事件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hsl0530hsl/article/details/88344225

拖拉(drag)指的是,用户在某个对象上按下鼠标键不放,拖动它到另一个位置,然后释放鼠标键,将该对象放在那里。

第一种 使用drag

拖拉的对象有好几种,包括元素节点、图片、链接、选中的文字等等。在网页中,除了元素节点默认不可以拖拉,其他(图片、链接、选中的文字)都是可以直接拖拉的。为了让元素节点可拖拉,可以将该节点的draggable属性设为true。

<div draggable="true">
  此区域可拖拉
</div>

draggable属性可用于任何元素节点,但是图片(<img>)和链接(<a>)不加这个属性,就可以拖拉。对于它们,用到这个属性的时候,往往是将其设为false,防止拖拉这两种元素。

注意,一旦某个元素节点的draggable属性设为true,就无法再用鼠标选中该节点内部的文字或子节点了。

当元素节点或选中的文本被拖拉时,就会持续触发拖拉事件,包括以下一些事件。

drag:拖拉过程中,在被拖拉的节点上持续触发(相隔几百毫秒)。

dragstart:用户开始拖拉时,在被拖拉的节点上触发,该事件的target属性是被拖拉的节点。通常应该在这个事件的监听函数中,指定拖拉的数据。

dragend:拖拉结束时(释放鼠标键或按下 ESC 键)在被拖拉的节点上触发,该事件的target属性是被拖拉的节点。它与dragstart事件,在同一个节点上触发。不管拖拉是否跨窗口,或者中途被取消,dragend事件总是会触发的。

dragenter:拖拉进入当前节点时,在当前节点上触发一次,该事件的target属性是当前节点。通常应该在这个事件的监听函数中,指定是否允许在当前节点放下(drop)拖拉的数据。如果当前节点没有该事件的监听函数,或者监听函数不执行任何操作,就意味着不允许在当前节点放下数据。在视觉上显示拖拉进入当前节点,也是在这个事件的监听函数中设置。

dragover:拖拉到当前节点上方时,在当前节点上持续触发(相隔几百毫秒),该事件的target属性是当前节点。该事件与dragenter事件的区别是,dragenter事件在进入该节点时触发,然后只要没有离开这个节点,dragover事件会持续触发。

dragleave:拖拉操作离开当前节点范围时,在当前节点上触发,该事件的target属性是当前节点。如果要在视觉上显示拖拉离开操作当前节点,就在这个事件的监听函数中设置。

drop:被拖拉的节点或选中的文本,释放到目标节点时,在目标节点上触发。注意,如果当前节点不允许drop,即使在该节点上方松开鼠标键,也不会触发该事件。如果用户按下 ESC 键,取消这个操作,也不会触发该事件。该事件的监听函数负责取出拖拉数据,并进行相关处理。

下面的例子展示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Dom Drag Event</title>
    <style type="text/css">
        div{
            width: 100px;
            height: 100px;
            background-color: gray;
            margin-bottom: 20px;
        }
        #draggable {
            position: absolute;
        }
    </style>
</head>
<body draggable="true">
    <div class="dropzone" id="0">
        <div id="draggable" draggable="true">
            该节点可拖拉
        </div>
    </div>
    <div class="dropzone" id="1"></div>
    <div class="dropzone" id="2"></div>
    <div class="dropzone" id="3"></div>
    <script>
        // 被拖拉节点
        var dragged;
        var dif = {};
        document.addEventListener('dragstart', function (event) {
            dif.x = event.clientX - event.target.offsetLeft;
            dif.y = event.clientY - event.target.offsetTop;
            // 保存被拖拉节点
            dragged = event.target;
            // 被拖拉节点的背景色变透明
            event.target.style.opacity = 0.5;
        }, false);

        document.addEventListener('dragend', function (event) {
            dragged.style.left = (event.clientX - dif.x) + "px";
            dragged.style.top = (event.clientY - dif.y) + "px";
            // 被拖拉节点的背景色恢复正常
            event.target.style.opacity = '';
        }, false);

        document.addEventListener('dragover', function (event) {
            // 防止拖拉效果被重置,允许被拖拉的节点放入目标节点
            event.preventDefault();
        }, false);

        document.addEventListener('dragenter', function (event) {
            // 目标节点的背景色变紫色
            // 由于该事件会冒泡,所以要过滤节点
            if (event.target.className === 'dropzone') {
                event.target.style.background = 'purple';
            }
        }, false);

        document.addEventListener('dragleave', function( event ) {
            // 目标节点的背景色恢复原样
            if (event.target.className === 'dropzone') {
                event.target.style.background = '';
            }
        }, false);

        document.addEventListener('drop', function( event ) {
            // 防止事件默认行为(比如某些元素节点上可以打开链接),
            event.preventDefault();
            if (event.target.className === 'dropzone') {
                // 恢复目标节点背景色
                event.target.style.background = '';
                // 将被拖拉节点插入目标节点
                dragged.parentNode.removeChild(dragged);
                event.target.appendChild( dragged );
            }
        }, false);
    </script>
</body>
</html>

如下是实现的效果:
在这里插入图片描述

关于拖拉事件,有以下几个注意点。

拖拉过程只触发以上这些拖拉事件,尽管鼠标在移动,但是鼠标事件不会触发。
将文件从操作系统拖拉进浏览器,不会触发dragstart和dragend事件。

dragenter和dragover事件的监听函数,用来取出拖拉的数据(即允许放下被拖拉的元素)。由于网页的大部分区域不适合作为放下拖拉元素的目标节点,所以这两个事件的默认设置为当前节点不允许接受被拖拉的元素。如果想要在目标节点上放下的数据,首先必须阻止这两个事件的默认行为。

第二种

除开使用 drag 事件之外,还可以使用原生的 mousedown | mousemove | mouseup 事件实现拖动效果,具体的代码实现如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>拖拽</title>
    <style>
        .draggable{
            width: 200px;
            height: 200px;
            background: gray;
            position: absolute;
            top: 0;
            left: 0;
        }
    </style>
    <script>
        window.onload=function () {
            let box=document.getElementsByClassName("draggable")[0];
            box.onmousedown=function (event) {
                let e=event||window.event;
                let distX=e.clientX-this.offsetLeft;
                let distY=e.clientY-this.offsetTop;

                document.onmousemove=function (event) {
                    let e=event||window.event;

                    box.style.left=e.clientX-distX+'px';
                    box.style.top=e.clientY-distY+'px';
                };

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

        };
    </script>
</head>
<body>
<div class="draggable"></div>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/hsl0530hsl/article/details/88344225
今日推荐