js 实现拖拽

825 阅读2分钟

1 前言

项目中可能会需要做拖拽的需求,接下来简单的实现一个拖拽的功能。

2 简介

HTML5提供专门的拖拽与拖放的API的方法。

3 代码实现

相关的属性

标签描述
dataTransfer托拽对象用来传递的媒介,使用一般为event.dataTransfer 或者e.dataTransfer
draggabledraggable默认是true,默认是可以被托拽的,如果我们想要实现托拽,最好是手动设置为true
ondragstart当拖拽元素开始被拖拽的时候触发的事件,此事件作用在被拖曳元素上
ondrag当拖拽元素移动的时候持续触发的事件,此事件作用在被拖曳元素上
ondragend当拖拽完成后触发的事件,此事件作用在被拖曳元素上
ondragover拖拽元素在目标元素上移动的时候触发的事件,此事件作用在目标元素上
ondragenter当拖曳元素进入目标元素的时候触发的事件,此事件作用在目标元素上
ondragleave当拖曳元素离开目标元素的时候触发的事件,此事件作用在目标元素上
ondrop被拖拽的元素在目标元素上同时鼠标放开触发的事件,此事件作用在目标元素上
event.preventDefault()或者e.preventDefault()阻止默认事件的方法,在ondragover中一定要阻止默认事件,否则ondrop事件不会被触发

静态页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>拖拽</title>
    <style type="text/css">
        div {
            width: 300px;
            height: 300px;
            float: left;
            margin: 20px;
            border: 1px dashed red;
        }

        img {
            cursor: pointer;
            width: 150px;
        }
    </style>
</head>
<body>
<div id="box1">
    <!-- draggable默认是true,默认是可以被拖拽的,
        如果我们像要实现拖拽,最好手动设置为true
    -->
    <img src="./drag.png" draggable="true" id="dragImg"/>
</div>
<div id="box2"></div>
</body>
</html>

如图

静态页面.png

拖拽实现

第一步 元素设置为可拖放draggable="true"

<img src="./drag.png" draggable="true" id="dragImg"/>

第二步 拖到何处,ondragover 事件规定被拖动的数据能够被放置到何处。默认地,数据/元素无法被放置到其他元素中。必须阻止元素的这种默认的处理方式。

元素.ondragover = function (e) {
    //这里需要阻止事件默认行为才能触发ondrop
    e.preventDefault();
};

// 具体实现
const box2 = document.querySelector("#box2");

box2.ondragover = function (e) {
    //这里需要阻止事件默认行为才能触发ondrop
    e.preventDefault();
};

第三步 进行放置,当放开被拖数据时,会发生drop事件。然后获取拖拽元素,并且加入到目标元素,完成拖拽。

元素.ondrop = function (e) {
    //获取拖拽时存储的拖拽标识
    var imgId = e.dataTransfer.getData("id");
    //获取拖拽元素,并且加入到目标元素
    this.appendChild(document.querySelector("#" + imgId));
};

// 具体实现
const box2 = document.querySelector("#box2");

box2.ondrop = function (e) {
    //获取拖拽时存储的拖拽标识
    const imgId = e.dataTransfer.getData("id");
    //获取拖拽元素,并且加入到目标元素
    this.appendChild(document.querySelector("#" + imgId));
};

效果如图

拖拽.gif

那么问题来了,在实现反拖拽需要怎么做?只需要再重新处理第二步 拖到何处第三步 进行放置就好了。

// 实现反拖拽
box1.ondragover = function (e) {
    e.preventDefault();
};

box1.ondrop = function (e) {
    //获取拖拽时存储的拖拽标识
    const imgId = e.dataTransfer.getData("id");
    //获取拖拽元素,并且加入到目标元素
    this.appendChild(document.querySelector("#" + imgId));
}

最终效果就能拖过来,拖过去了,如图

最终效果.gif

4 完成代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>拖拽</title>
    <style type="text/css">
        div {
            width: 300px;
            height: 300px;
            float: left;
            margin: 20px;
            border: 1px dashed red;
        }

        img {
            cursor: pointer;
            width: 150px;
        }
    </style>
</head>
<body>
<div id="box1">
    <!-- draggable默认是true,默认是可以被拖拽的,
        如果我们像要实现拖拽,最好手动设置为true
    -->
    <img src="./drag.png" draggable="true" id="dragImg"/>
</div>
<div id="box2"></div>
<script type="text/javascript">
    const box1 = document.querySelector("#box1");
    const box2 = document.querySelector("#box2");
    const img = document.querySelector("img");

    /**** 拖拽元素相关事件 ****/
    img.ondragstart = function (e) {
        //设置拖拽的标识 (在其他事件对象中就会获取到存储的这个值)
        e.dataTransfer.setData("id", e.target.id);
    };

    box2.ondragover = function (e) {
        //这里需要阻止事件默认行为才能触发ondrop
        e.preventDefault();
    };

    box2.ondrop = function (e) {
        //获取拖拽时存储的拖拽标识
        const imgId = e.dataTransfer.getData("id");
        //获取拖拽元素,并且加入到目标元素
        this.appendChild(document.querySelector("#" + imgId));
    };

    box1.ondragover = function (e) {
        e.preventDefault();
    };

    box1.ondrop = function (e) {
        //获取拖拽时存储的拖拽标识
        const imgId = e.dataTransfer.getData("id");
        //获取拖拽元素,并且加入到目标元素
        this.appendChild(document.querySelector("#" + imgId));
    }
</script>
</body>
</html>

5 最后

各位,早点下班,顺便留下你的脚印,谢谢