原生 JS 快速实现拖放

拖放是很常见的一种交互效果,很多时候我们都会借助于第三方的控件来实现,其实用原生 js 实现起来也非常的方便。接下来我们就用原生 js 和 css 快速实现拖放效果

html

<body>
<div class="droppable">
<div class="draggable" draggable="true"></div>
</div>
<div class="droppable"></div>
<div class="droppable"></div>
<div class="droppable"></div>
<div class="droppable"></div>
</body>

注意点: 1. 容器的的 class 为 droppable,用于接收被拖拽的元素,可被拖拽的元素 class 为 draggable,同时设置 draggable 属性为 true,表示该元素可以被拖拽。 2. 默认情况下,只有图片、链接还有被选中的文字能被拖拽,其他元素需要设置 draggable 为 true 才能被拖拽。所以为了凸显 draggable 的用法,这里使用 <div> 而不是 <image> 来作为被拖拽的元素。

css

在实现样式的时候,除了实现静态的样式,一些过渡状态也需要增加样式以提升视觉体验:

  1. 元素被拖动的过程中增加边框等效果; 2. 当元素被拖动到容器上方时,容器也应增加样式表明容器可以接收一个被拖拽的元素。
body {
background-color: darksalmon;
} .draggable {
background-image: url("http://source.unsplash.com/random/150x150");
position: relative;
height: 150px;
width: 150px;
top: 5px;
left: 5px;
cursor: pointer;
} .droppable {
display: inline-block;
height: 160px;
width: 160px;
margin: 10px;
border: 3px salmon solid;
background-color: white;
} .dragging {
border: 4px yellow solid;
} .drag-over {
background-color: #f4f4f4;
border-style: dashed;
} .invisible {
display: none;
}

注意点: 1. 图片来源于 百度; 2. .dragging 为 draggable 元素正在被拖动的状态,增加黄色 border; 3. .drag-over 为 draggable 元素被拖动到容器上方时容器的状态,增加灰色虚线 border。

js

最后,我们需要通过 js 监听 draggable 和 droppable 的相关的事件。

// 查询draggable和droppable
const draggable = document.querySelector(".draggable");
const droppables = document.querySelectorAll(".droppable"); // 监听draggable的相关事件
draggable.addEventListener("dragstart", dragStart);
draggable.addEventListener("dragend", dragEnd); function dragStart() {
this.className += " dragging";
setTimeout(() => {
this.className = "invisible";
}, 0);
} function dragEnd() {
this.className = "draggable";
} // 监听droppable的相关事件
for (const droppable of droppables) {
droppable.addEventListener("dragover", dragOver);
droppable.addEventListener("dragleave", dragLeave);
droppable.addEventListener("dragenter", dragEnter);
droppable.addEventListener("drop", dragDrop);
} function dragOver(e) {
e.preventDefault();
} function dragEnter(e) {
e.preventDefault();
this.className += " drag-over";
} function dragLeave(e) {
this.className = "droppable";
} function dragDrop(e) {
this.className = "droppable";
this.append(draggable);
}

注意点: 1. 当 draggable 元素被拖动时,原来容器中的 draggable 元素并不会消失,需要我们手动将其隐藏(class 设置为 invisible),如果同步操作会立马触发 dragend 事件导致拖动效果消失,所以在 setTimeout 的回调中异步设置可确保拖动操作开始后再隐藏 draggable 元素; 2. 在 dragEnter 和 dragOver 方法中我们需要通过 preventDefault 来取消事件以表明容器是一个合法的 droppable 元素,不然容器的 drop 事件将无法触发,接下来的操作也将无法进行,详细解释请参考 MDN DropTarget; 3.在 dragDrop 方法中直接使用 append 方法将 draggable 元素移动至当前容器下面。


完整示例演示:https://codehhr.gitee.io/web/jsdrag/

The_End

原生JS快速实现拖放的更多相关文章

  1. 原生js快速渲染dom节点

    function renderDom(str){ var _div = document.createElement('div'); _div.innerHTML = str; var dom_tem ...

  2. 原生JS实现"旋转木马"效果的图片轮播插件

    一.写在最前面 最近都忙一些杂七杂八的事情,复习软考.研读经典...好像都好久没写过博客了... 我自己写过三个图片轮播,一个是简单的原生JS实现的,没有什么动画效果的,一个是结合JQuery实现的, ...

  3. 【前端性能】必须要掌握的原生JS实现JQuery

    很多时候,我们经常听见有人说jquery有多快多快.在这个各种类库满天飞的时候,不得不说的是,能有原生JS快吗? 是的,明显原生JS要更快,因为诸如JQuery这样的库必须要兼容各种浏览器和低版本和许 ...

  4. 用原生JS读写CSS样式的方法总结

    为了日后方便查询,本人翻阅了一些资料总结了以下方法,仅限原生JS,如有不对的地方欢迎指出!只求大家看完觉得有学到点什么就OK了!   一.可以通过DOM节点对象的style对象(即CSSStyleDe ...

  5. AJAX请求和跨域请求详解(原生JS、Jquery)

    一.概述 AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. AJAX = 异步 JavaScript 和 XML,是一种用于创建快速动态网页的技术.通过在后台与服务器进行少量数 ...

  6. 原生js仿jquery--animate效果

    效果 代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  7. JQuery&原生js ——实现剪刀石头布小游戏

    前言 jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库( 或JavaScript框架).jQuery设计的宗旨是“write L ...

  8. 通过游戏认识 --- JQuery与原生JS的差异

      前言 jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库( 或JavaScript框架).jQuery设计的宗旨是“write ...

  9. 原生js写ajax请求(复习)

    今天本地想测试一个接口,不想用框架想用js快速完成,突然发现,我居然忘了这个最基本的代码.好吧,只能复习一波. 在框架泛滥的今天,用惯$.ajax(),axios,superAgent等框架的你们,还 ...

随机推荐

  1. 【HTB系列】靶机Frolic的渗透测试详解

    出品|MS08067实验室(www.ms08067.com) 本文作者:大方子(Ms08067实验室核心成员) Hack The Box是一个CTF挑战靶机平台,在线渗透测试平台.它能帮助你提升渗透测 ...

  2. GPLT L2-010 排座位 (并查集)

    Tips: 数据范围较小时可把二维数组当做map<pair<int,int>,int>使用. #include <bits/stdc++.h> using name ...

  3. Educational Codeforces Round 95 (Rated for Div. 2) B. Negative Prefixes (贪心,构造)

    题意:给你一串长度为\(n\)的序列,有的位置被锁上了,你可以对没锁的位置上的元素任意排序,使得最后一个\(\le0\)的前缀和的位置最小,求重新排序后的序列. 题解:贪心,将所有能动的位置从大到小排 ...

  4. 大数据开发-从cogroup的实现来看join是宽依赖还是窄依赖

    前面一篇文章提到大数据开发-Spark Join原理详解,本文从源码角度来看cogroup 的join实现 1.分析下面的代码 import org.apache.spark.rdd.RDD impo ...

  5. C++ 结构体 segment fault

    形如 struct node { int key; int height; int size; //tree node 个数 node *left, *right; node(int x) : key ...

  6. codeforces 1019B The hat 【交互题+二分搜索】

    题目链接:戳这里 学习题解:戳这里

  7. ewebeditor 路径

    1.关键文件的名称和路径Admin_Login.asp 登录页面Admin_Default.asp 管理首页Admin_Style.aspAdmin_UploadFile.aspUpload.aspA ...

  8. vuepress & package.json lock version

    vuepress & package.json lock version npm 锁版 bug npm lock version holy shit { "name": & ...

  9. Google Chrome All In One

    Google Chrome All In One Chrome Experiments Chrome 测试版 Chrome 开发者版 Chrome Canary 版 chrome://welcome/ ...

  10. Linux Schedule Cron All In One

    Linux Schedule Cron All In One 定时任务 / 定时器 GitHub Actions Scheduled events Cron syntax has five field ...