Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >HTML5 drag和drop的亲手实践

HTML5 drag和drop的亲手实践

作者头像
嘿嘿嘿
发布于 2018-09-10 08:32:46
发布于 2018-09-10 08:32:46
1K00
代码可运行
举报
文章被收录于专栏:陈纪庚陈纪庚
运行总次数:0
代码可运行

起因

最近在公司打杂的时候,突然分到了一个锅,就是要支持一个新的功能:用户可以通过拖曳组件来改变组件的顺序。因此,这阵子就看了一下网上的一些drag和drog的文章以及W3C的介绍,然后自己亲手实践了一下,毕竟打码,才能变得更强。 首先,先放一个我的demo,大家可以去那里随便拖动一下玩一玩: https://chenjigeng.github.io/example/drag.html

知识储备

与drag和drog有关的属性和事件
  • draggable属性: 如果你想让一个元素变得可以拖曳的话,那么你就必须设置它的draggable=true,如下
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<div class='target' draggable="true"></div>

这样,该元素就可以拖动了

  • ondragstart: 当元素开始被拖动时,触发该事件,目标对象是被拖动的元素
  • ondragover: 当被拖动元素在悬挂元素上移动的时候,该事件触发。目标对象是被拖动元素悬挂的那个元素。
  • ondragleave: 当被拖动元素离开悬挂元素时,触发该事件。目标对象是被拖动元素悬挂的那个元素。
  • ondrop: 当鼠标松开被拖动元素的时候,触发该事件。目标对象是被拖动元素悬挂的那个元素。
  • ondragend: 当鼠标松开被拖动元素的时候,触发该事件。目标对象是被拖动的元素。其中,ondrop事件会先于ondragend事件触发。
  • event.preventDefault: 当触发ondragover事件的时候,必须使用event.preventDefault(),否则的话,ondrop事件就不会触发
  • event.dataTransfer.effectAllowed:设置或返回被拖动元素允许发生的拖动行为。可设置的属性很多,这里我们就不细说,感兴趣的可以去查下,一般来说,我们都设置为"move".
插入节点的方法
  • 将节点插入到另一个节点前面,代码如下
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 function insertBefore(insertNode, node) {
       node.parentNode.insertBefore(insertNode, node)
 }

这个其实比较简单,就是找到节点的父亲,然后将要插入的节点放到节点的前面。

  • 将节点插入到另一个节点后面,代码如下图
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 function insertAfter(insertNode, node) {
       if (node.nextElementSibling) {
         insertBefore(insertNode, node.nextElementSibling)
       } else {
         node.parentNode.appendChild(insertNode)
       }
 }

这个其实也挺简单的,就是如果该节点有兄弟节点的话,那么就将插入节点放到它兄弟节点的前面,否则,则说明该节点是父节点的最后一个节点,因此直接将插入节点放到父节点的末尾。

实践

在这里,我们要做的就是一个支持各个图片拖曳来交换位置的玩意,不过,当图片交换位置的时候,不单单是图片交换位置,而是包含图片的容器交换位置。

1.我们先放置几张图片,并且将它们的dragable设置为true,这样它们就可以拖动了。代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<body>
    <div class='target' draggable="true">
      <img src="./imgs/1.jpeg" alt="1">
    </div>
    <div class='target' draggable="true">
      <img src='./imgs/2.jpg' />
    </div>
    <div class='target' draggable="true">
      <img src="./imgs/3.jpg" alt="ss">
    </div>    
    <div class='target' draggable="true">
      <img src="./imgs/4.jpg" alt="ss">
    </div>   
  </body>

效果:

2.为每个div都设置一个ondragstart函数,当该函数触发的时候,进行初始化操作,比如记录当前的目标对象,拖动目标的y值,以及设置拖动的效果。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 拖动的目标对象
let target = ''
// 拖动的目标对象的y值
let targetOffsetTop = 0
// 当元素开始被拖动时,触发该事件,目标对象是被拖动的元素
function handleDragStart(ev) {
  target = findTarget(ev.target)
  targetOffsetTop = ev.target.offsetTop
  ev.dataTransfer.effectAllowed = 'move'
}
// 找到类名为target的目标对象
function findTarget(node) {
  if (!node || node == document) {
    return null
  }
  if (node.classList.contains('target')) {
    return node;
  }
  return findTarget(node.parentNode)
}

3.为每个div注册一个ondragover事件和ondragleave事件,在ondragover事件里,主要是调用event.preventDefault来防止ondrog不会被触发,并且为了看起来更明显,当ondragover事件触发的时候,为目标对象增加一个dotted类。当ondragleave事件触发的时候,则把dotted类从目标对象移除。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 当被拖动元素在悬挂元素上移动的时候,该事件触发。目标对象是被拖动元素悬挂的那个元素。
// 必须执行event.preventDefault(),不然的话ondrop不会触发
function handleDragOver(ev) {
  ev.preventDefault();
  ev.target.classList.add('dotted')
}
// 当被拖动元素离开悬挂元素时,触发该事件。目标对象是被拖动元素悬挂的那个元素。
function handleDragLeave(ev) {
  ev.target.classList.remove('dotted')
}

4.为每个div注册ondrog事件和ondragend事件,ondrog事件是重点,它主要是根据被拖动元素和被拖动元素悬挂的那个元素的坐标,来决定是要将被拖动元素插入到悬挂元素的前面还是后面。而ondragend主要是用于将target设置为null,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 当鼠标松开被拖动元素的时候,触发该事件。目标对象是被拖动元素悬挂的那个元素。
function handleDrog(ev) {
  let resultOffsetTop = ev.target.offsetTop
  if (targetOffsetTop < resultOffsetTop) {
    insertAfter(target, findTarget(ev.target))
  }
  else {
    insertBefore(target, findTarget(ev.target))
  }
  ev.target.classList.remove('dotted')
}
// 将节点插入到另一个节点前面
function insertBefore(insertNode, node) {
  node.parentNode.insertBefore(insertNode, node)
}
// 将节点插入到另一个节点后面
function insertAfter(insertNode, node) {
  if (node.nextElementSibling) {
    insertBefore(insertNode, node.nextElementSibling)
  } else {
    node.parentNode.appendChild(insertNode)
  }
}
// 当松开鼠标的时候,触发该事件。目标对象是被拖动的对象
function handleDragEnd(ev) {
  target = null
}

这样子,我们就实现了一个可以通过拖曳来改变图片顺序的一个小玩意啦~完整的代码放到https://github.com/chenjigeng/something 上了~有兴趣的可以git clone下来跑一跑

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-07-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
JavaScript 学习-50.实现页面菜单拖放(Drag 和 Drop)
拖放是一种常见的操作,即抓取对象以后从一个位置拖到另一个位置。 在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放。
上海-悠悠
2023/01/03
1.5K0
JavaScript 学习-50.实现页面菜单拖放(Drag 和 Drop)
JavaScript进阶之实现拖拽
如果不设置这段代码,会发生奇怪的现象,这是因为浏览器有自己的对图片和一些其他元素的拖放处理,会在我们拖放时自动运行,这与我们的拖放处理产生了冲突。
落落落洛克
2021/01/08
2.9K0
JavaScript进阶之实现拖拽
彻底搞懂拖拽——基于鼠标事件的拖拽以及基于HTML5 API的拖拽完整实现
  一个典型的拖拽操作是这样的:用户用鼠标选中一个可拖动的(draggable)元素,移动鼠标到一个可放置的(droppable)元素,然后释放鼠标。 在操作期间,会触发一些事件类型,有一些事件类型可能会被多次触发(比如drag 和 dragover 事件类型)。   这里涉及几个知识点:
从入门到进错门
2018/12/05
3.6K0
彻底搞懂拖拽——基于鼠标事件的拖拽以及基于HTML5 API的拖拽完整实现
HTML5 进阶系列:拖放 API 实现拖放排序
本文介绍了如何使用 HTML5 的拖放 API 实现一个简单的拖放排序功能。首先介绍了如何为元素设置拖放 API,然后通过一个示例展示了如何实现拖放排序。在示例中,使用了 dataTransfer 对象来存储数据,并通过 setDragImage() 方法来设置拖放图标。最后,指出了在 IE 和 iOS 上需要使用特定的插件来支持拖放排序。
IMWeb前端团队
2017/12/29
2.1K0
HTML5 拖放
拖放(Drag 和 drop)在WEB软件应用中是一种常见的操作,就是用户可以用鼠标点击对象以后拖到另一个位置。
十分钟空间
2022/08/17
1.8K0
HTML5-拖拽
将div中元素拖到另一个 中 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> *{ margin: 0; padding: 0; } .div1{ width: 200px; height: 200px;
eadela
2019/09/29
9790
HTML5 - 拖放
拖放是一种常见的特性,即抓取对象以后拖到另一个位置。在H5中,任何元素都支持拖放,但是需要注意的是,有些元素存有默认行为(如a元素),应当取消该元素的默认行为。
1338335202用户
2022/12/19
1.8K0
HTML5 - 拖放
HTML5原生拖放事件的学习与实践
之前学习了 HTML5 的拖放事件,开发中也用到了拖拽组件。为了厘清整体的逻辑,专门做了一个小例子。
心谭博客
2020/04/20
1.3K0
HTML5原生拖放事件的学习与实践
HTML5、JS实现元素拖拽排序
先介绍一下html5的drag属性,拖放(Drag 和 drop)是 HTML5 标准的组成部分。想要启用drag,只要给元素加上draggable="true"就行了(Safari 5.1.2除外)。
江拥羡橙
2023/11/16
9020
HTML5、JS实现元素拖拽排序
javascript对dom节点拖拽的简单实现(drag特性)
直接看代码 ,一切尽在注释中 <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>Drag</title> <style type="text/css"> *{ margin: 0px; padding:0px; } #con{ width:100%; height:500px; border:1px dotted #999; } #img{ margin-left: 10px;
lonelydawn
2018/02/09
1.6K0
javascript对dom节点拖拽的简单实现(drag特性)
drag事件详解:html5鼠标拖动排序及resize实现方案分析及实践
对列表进行拖动排序,尺寸改变。之前一般会使用jQuery-UI(interactjs更加纯粹)。其通过mousedown、mousemove、mouseup这三个事件来实现页面元素被鼠标拖拽的效果。vue-drag-resize vuedraggable等包也大抵如此:https://codepen.io/lujun-zhou/pen/LYybXNx。
周陆军博客
2023/05/07
6.9K1
HTML5 的拖放(实例:两个div之间拖放图片)
首先,为了使元素(如本图片)可拖动,把 draggable 属性设置为 true :
书童小二
2018/09/03
2.5K0
HTML5 的拖放(实例:两个div之间拖放图片)
H5拖放原生js将图片拖放另外一个元素里
拖放是一种常见的特性,即抓取对象以后拖到另一个位置。在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放
青梅煮码
2023/03/02
2.3K0
H5拖放原生js将图片拖放另外一个元素里
前端文件上传功能实现原理
最近在做一个上传文件的功能,用的elementUI框架的el-upload组件,为了探究其原理,就想到了有两种上传方式,第一种是type为file的input选择上传,另一个就是拖拽的上传方式,拖拽一直没弄清原理,借这次机会彻底搞清楚。
用户6256742
2024/05/18
2280
前端文件上传功能实现原理
前端里的拖拖拽拽了解一下?
拖拽交互常见于各种前端编辑器里,而“编辑器”是一个集成前端技术能力的综合性工程,其中就会涉及到各种形式的拖拽交互,因为“拖拽”是提升用户体验的重要交互方式,所以需要对拖拽的交互效果做各种定制化,作为开发者理应熟练掌握“拖拽”的使用!
小东同学
2022/07/29
5.3K1
前端里的拖拖拽拽了解一下?
前端拾零02—H5拖放总结
前端拾零收录日常开发中一些很常见很基础的前端操作,省去每次google甚至答案错误的烦恼
CS逍遥剑仙
2018/08/17
4.3K1
前端拾零02—H5拖放总结
从零开始学 Web 之 HTML5(四)拖拽接口,Web存储,自定义播放器
ondrag :应用于拖拽元素,整个拖拽过程都会持续调用; ondragstart:应用于拖拽元素,当拖拽开始时调用; ondragleave:应用于拖拽元素,拖拽过程中,当鼠标离开拖拽元素范围时调用; ondragend :应用于拖拽元素,当拖拽结束时调用。
Daotin
2018/08/31
1.6K0
从零开始学 Web 之 HTML5(四)拖拽接口,Web存储,自定义播放器
前端拾零02—H5原生拖放总结 【原创】
前端拾零收录日常开发中一些很常见很基础的前端操作,省去每次google甚至答案错误的烦恼
CS逍遥剑仙
2018/09/26
2K0
前端学习(4)~html5详解(二)
在HTML5的规范中,我们可以通过为元素增加 draggable="true" 来设置此元素是否可以进行拖拽操作,其中图片、链接默认是开启拖拽的。
Vincent-yuan
2020/02/23
7760
html5鼠标拖动排序及resize实现方案分析及实践
对列表进行拖动排序,尺寸改变。之前一般会使用jQuery-UI。其通过mousedown、mousemove、mouseup这三个事件来实现页面元素被鼠标拖拽的效果。vue-drag-resize vuedraggable等包也大抵如此:https://codepen.io/lujun-zhou/pen/LYybXNx。
周陆军
2021/07/13
3.4K0
相关推荐
JavaScript 学习-50.实现页面菜单拖放(Drag 和 Drop)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验