【重构前端知识体系之HTML】HTML5的新特性——拖放

「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。

【重构前端知识体系之HTML】HTML5的新特性——拖放

内容速递

image-20220222182532088

引言

在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放。

拖放的操作,多用在拖拽排序列表、游戏拼图等。

下文中出现拖放拖拽表达同一个意思。

官方介绍

HTML 拖放(Drag and Drop)接口使应用程序能够在浏览器中使用拖放功能。例如,用户可使用鼠标选择可拖拽(draggable)元素,将元素拖拽到可放置(droppable)元素,并释放鼠标按钮以放置这些元素。

拖拽操作期间,会有一个可拖拽元素的半透明快照跟随着鼠标指针。

文档

可以查看拖放的一些API,包含了相关接口的说明、在应用程序中加入拖放支持的基本步骤,以及相关接口的使用简介。

文档地址:官方文档

拖拽事件

主要有八个主要的事件,完成拖拽着歌过程一系列的事件响应。

事件 事件函数 触发时刻
drag ondrag 当拖拽元素或选中的文本时触发。
dragend ondragend 当拖拽操作结束时触发 (比如松开鼠标按键或敲“Esc”键).。
dragenter ondragenter 当拖拽元素或选中的文本到一个可释放目标时触发。
dragexit ondragexit 当元素变得不再是拖拽操作的选中目标时触发。
dragleave ondragleave 当拖拽元素或选中的文本离开一个可释放目标时触发。
dragover ondragover 当元素或选中的文本被拖到一个可释放目标上时触发(每100毫秒触发一次)。
dragstart ondragstart 当用户开始拖拽一个元素或选中的文本时触发。
drop ondrop 当元素或选中的文本在可释放目标上被释放时触发。

拖拽核心

什么是可拖拽的?

有同学问了,上面不是说任何元素都能够拖放吗?为啥我平时拖不动?

那平时拖动了,就不叫功能了,叫BUG!

为了使元素可拖动,需要把 draggable 属性设置为 true

<div draggable="true"></div>
复制代码

拖起

通过ondragstart 事件,调用dataTransfer.setData() 方法设置被拖数据的数据类型和值。

<script>
  window.addEventListener('DOMContentLoaded', () => {
    const element = document.getElementById("p1");
    element.addEventListener("dragstart", (ev) => {
      ev.dataTransfer.setData("text/plain", ev.target.id);
    });
  });
</script>

<p id="p1" draggable="true">This element is draggable.</p>
复制代码

拖拽数据

应用程序可以在拖拽操作中包含任意数量的数据项。每个数据项都是一个 string类型,典型的 MIME 类型,如:text/html

function dragstart_handler(ev) {
  // 添加拖拽数据
  ev.dataTransfer.setData("text/plain", ev.target.innerText);
  ev.dataTransfer.setData("text/html", ev.target.outerHTML);
  ev.dataTransfer.setData("text/uri-list", ev.target.ownerDocument.location.href);
}
复制代码

想了解更多的xdm,可以查看 推荐拖拽类型 (en-US) 了解可拖拽的常见数据类型(如文本、HTML、链接和文件)。

拖拽图像

拖拽过程中,浏览器会在鼠标旁显示一张默认图片。

通过 setDragImage()方法自定义一张图片。

function dragstart_handler(ev) {
  var img = new Image();
  img.src = 'example.gif';
  ev.dataTransfer.setDragImage(img, 10, 10);
}
复制代码

当然如果需要图片的样式,可以使用基本的拖拽数据类型。

拖拽效果

在拖拽的过程中,或者鼠标停留在元素上时的反馈有 3 个效果可以定义:

  1. copy 表明被拖拽的数据将从它原本的位置拷贝到目标的位置。
  2. move 表明被拖拽的数据将被移动。
  3. link 表明在拖拽源位置和目标位置之间将会创建一些关系表格或是连接。

通过dropEffect来设置

function dragstart_handler(ev) {
  ev.dataTransfer.dropEffect = "copy";
}
复制代码

放置

当拖拽一个项目到 HTML 元素中时,浏览器默认不会有任何响应。

有拖起那么必有放置,除非你犟!不松下鼠标!

这里需要借助ondrop和ondragover两个事件来完成!dataTransfer.getData()来设置新的数据。

<script>
function dragover_handler(ev) {
 ev.preventDefault();
 ev.dataTransfer.dropEffect = "move";
}
function drop_handler(ev) {
 ev.preventDefault();
 var data = ev.dataTransfer.getData("text/plain");
 ev.target.appendChild(document.getElementById(data));
}
</script>

<p id="target" ondrop="drop_handler(event)" ondragover="dragover_handler(event)">Drop Zone</p>
复制代码

一个拖拽案例

一个互相拖放的案例,可以从A->B,B->A。

思路:之前实现单方面的拖拽,是一个拖,一个放。那么这两者彼此都这样设置一番呢,岂不是可以实现互相的拖放?

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"> 
<title>drag</title>
<style type="text/css">
#div1, #div2 {
	float:left; 
	width:200px; 
	height:80px; 
	margin:10px;
	border:1px solid #aaaaaa;
}
</style>
<script>
function allowDrop(ev) {
	ev.preventDefault();
}

function drag(ev) {
	ev.dataTransfer.setData("Text",ev.target.id);
}

function drop(ev) {
	ev.preventDefault();
	var data=ev.dataTransfer.getData("Text");
	ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>

<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
	<img src="https://img0.baidu.com/it/u=1047123058,3465364298&fm=253&fmt=auto&app=138&f=JPEG?w=720&h=405" draggable="true" ondragstart="drag(event)" id="drag1" width="200" height="80">
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>

</body>
</html>
复制代码

效果

image-20220222180034593

一个好用的拖拽插件

既然是学习拖拽的,那么推荐一个比较好用的Vue的拖拽组件,vue.draggable,它的官网地址:Github地址

image-20220222180336664

里面也有其作者写的一个js公用版的。

也把中文文档地址贴一下吧,希望对你学习拖拽有帮助。中文文档地址

总结

写那么多,总感觉意犹未尽!

差一个拖拽的小游戏案例?(等待安排,时间紧急,需要排期!!!)

重构前端知识体系,你要一起吗?

博客说明与致谢

文章所涉及的部分资料来自互联网整理,其中包含自己个人的总结和看法,分享的目的在于共建社区和巩固自己。

引用的资料如有侵权,请联系本人删除!

感谢万能的网络,W3C,菜鸟教程等!

如果你感觉对你有帮助的话,不妨给我点赞鼓励一下,好文记得收藏哟!

关注我一起成长!

幸好我在,感谢你来!

Guess you like

Origin juejin.im/post/7067765414687670280