原生 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. Pytest(10)assert断言

    前言 断言是写自动化测试基本最重要的一步,一个用例没有断言,就失去了自动化测试的意义了.什么是断言呢? 简单来讲就是实际结果和期望结果去对比,符合预期那就测试pass,不符合预期那就测试 failed ...

  2. JVM之堆参数

    1.Java 7和Java 8区别 Java 7堆结构 JDK 1.8之后将最初的永久代取消了,由元空间取代. 在Java8中,永久代已经被移除,被一个称为元空间的区域所取代.元空间的本质和永久代类似 ...

  3. The Department of Redundancy Department

    Write a program that will remove all duplicates from a sequence of integers and print the list of un ...

  4. 2020牛客暑期多校训练营(第八场)Game SET

    传送门:Game SET 题意 一套牌有四种属性,每种属性都有三种特征,shapes (one, two, or three), shape (diamond, squiggle, or oval), ...

  5. F - To Add Which?

    Description There is an integer sequence with N integers. You can use 1 unit of cost to increase any ...

  6. Educational Codeforces Round 102 (Rated for Div. 2) D. Program (思维,前缀和)

    题意:给你一个只含\(+\)和\(-\)的字符串,给你一个数\(x\),\(x\)初始为\(0\),随着字符串的遍历会加一减一,现在有\(m\)个询问,每个询问给出一个区间\([l,r]\)表示将这个 ...

  7. Codeforces Round #667 (Div. 3) D. Decrease the Sum of Digits (贪心)

    题意:给你一个正整数\(n\),每次可以对\(n\)加一,问最少操作多少次是的\(n\)的所有位数之和不大于\(s\). 题解:\(n\)的某个位置上的数进位,意味这后面的位置都可以被更新为\(0\) ...

  8. 连接MongoDb数据库 -- Python

    1.安装完mongoDb数据库后,如果需要我们的Python程序和MongoDb数据库进行交互,需要安装pymongo模块: 安装方式:采用pip install pymongo的方式 Microso ...

  9. ElasticSearch 集群 & 数据备份 & 优化

    ElasticSearch 集群相关概念 ES 集群颜色状态 ①. - 红色:数据都不完整 ②. - 黄色:数据完整,但是副本有问题 ③. - 绿色:数据和副本全都没有问题 ES 集群节点类型 ①. ...

  10. Python——控制鼠标键盘

    一.安装包 pip install pynput 二.引用包 from pynput import mouse,keyboard 三.控制鼠标 from pynput.mouse import But ...