likes
comments
collection
share

一个例子,带你了解神秘的 DataTransfer

作者站长头像
站长
· 阅读数 52

关于 DataTransfer

在开发中,涉及到文件上传的场景比比皆是,尤其是在一些 2B、2G 的产品中,为了方便用户操作,许多项目在手动上传的同时还需要支持「 文件拖拽上传」,以此来提高用户体验。一说到「 文件拖拽上传」,我们就不得不提到 DataTransfer 对象。

DataTransfer 对象好比一个使者,他负责携带用户拖拉的文件,并将文件数据信息传递到用户最终拖放的地方。DataTransfer 业务范围很广,他可以携带一种或者多种数据,同时也支持一种或者多种的数据类型。除此之外,DataTransfer 还有一个很大的权力,他可以修改用户的拖拉数据,并且限制用户的行为,比如限制用户的拖放类型,详情可可以参考 DataTransfer

因此,了解 DataTransfer 是使用「 文件拖拽」的必修课。

一个例子看懂 DataTransfer

概述

描述:页面有一个文本输入框,我们可以将输入的文字存到 DataTransfer 中,并在蓝色区块拖放置黄色区块的时候,将文字写入黄色框中,而这些事情,都是通过 DataTransfer 来完成。

 <div class="inputWrap">
     <span>输入你的资料</span>
     <input type="text" id="dragInput" />
</div>
<div class="dragWrap">
    <div draggable="true" class="box box-dragger"></div>
    <div droppable="true" class="box box-dropper"></div>
</div>
一个例子,带你了解神秘的 DataTransfer

代码实现

当你拖动一个区块(文件)时,最先触发的是 dragstart 事件,因此,我们可以在 dragstart 触发的时候将输入框文字信息写入到 DataTransfer 中:

const dragger = document.querySelector(".box-dragger");
const dragInput = document.querySelector("#dragInput");
let dragTemp;

dragger.addEventListener("dragstart", (e) => {
    dragTemp = e.target;
    // 文字信息写入
});

在监听拖拽事件的时候要阻止 dragover 的默认行为,才能成功地触发 drop 事件,并将拖拽元素成功放入目标元素中

 dropper.addEventListener("dragover", (e) => {
     e.preventDefault();
 });

使用 dataTransfer.setData 修改数据

dataTransfer 可以通过 setData(format, data) 来写入数据

dragger.addEventListener("dragstart", (e) => {
    dragTemp = e.target;
    e.dataTransfer.setData("text/plain", dragInput?.value ?? "");
});

使用 dataTransfer.getData 获取数据

dataTransfer 可以利用 getData(format) 读取拖拽数据,拖拽事件结束时,会触发 drop 事件,我们在这里读取刚才写入的数据,并放入拖放目标里面:

const dropper = document.querySelector(".box-dropper"); // 拖放目标
dropper.addEventListener("drop", (e) => {
    // 数据读取
    const dragText = e.dataTransfer.getData("text/plain"); 
    dragTemp.style.margin = "10px";
    dragTemp.style.width = "180px";
    dragTemp.style.height = "180px";
    dragTemp.append(dragText);
    e.target.appendChild(dragTemp);
    e.target.style.color = "#fff";
    e.target.style.background = "#FFC48B";
    dropper.style.border = "none";
});

对拖拽元素放入目标元素的过程做一些视觉上的交互

dropper.addEventListener("dragenter", (e) => {
    dropper.style.background = "#d4965a";
    dropper.style.border = "1px dashed #0a0a0a";
});
​
dropper.addEventListener("dragleave", () => {
    dropper.style.background = "#FFC48B";
    dropper.style.border = "none";
});

最终效果

一个例子,带你了解神秘的 DataTransfer

以上例子,是绝大部分拖拽场景中需要使用到的,如果你动手实现得到了最终效果,你就已经开始了解了 DataTransfer 这个神秘的对象。接下来,我们聊聊它的属性和方法。

DataTransfer 对象属性和方法

DataTransfer 对象属性

DataTransfer.dropEffect

获取当前的拖放操作类型,或者设置当前的拖放操作类型。类型的值可能为: nonecopylinkmove。当设置不同的类型时,拖拽效果会有所不同,主要体现在拖放鼠标的样式上:

一个例子,带你了解神秘的 DataTransfer

DataTransfer.effectAllowed

提供可能的所有类型的操作。操作类型可能为:

  • none:不允许拖拽。鼠标保持禁止状态
  • copy:允许复制
  • copyLink:允许复制和链接
  • copyMove:允许复制和移动操作
  • link:允许在新位置建立链接
  • linkMove:允许链接和移动操作
  • move:允许将元素移动到新位置
  • all :允许任意操作
  • uninitialized :表示未初始化,效果和 all 一样

effectAlloweddropEffect 的区别:

  • effectAllowed 主要在 dragstart 事件中使用,dropEffect 属性主要在 dragenterdragover 事件中使用
  • effectAllowed 会限制 dropEffect 的值,dropEffect 属性只能设置 effectAllowed 允许的值;举个简单的例子,如果设置 effectAllowed 的值为 link,设置 dropEffect 的值为 copy,两者不一致拖拉是无效的,没法响应 drop 事件。
dragger.addEventListener("dragstart", (e) => {
    e.dataTransfer.effectAllowed = "link";
});

// dropper
dropper.addEventListener("dragover", (e) => {
    event.dataTransfer.dropEffect = "move";
});

但是大部分场景都是拖拉拽,所以这个属性用得并不多。

DataTransfer.files

拖拽的本地文件列表。如果拖动操作不涉及文件,则 files.length 为 0。除了拖拽,当用户复制文件、粘贴文件也能在 DataTransfer 中拿到文件数据。

DataTransfer.items(只读)

只读属性,用来获取拖拽的数据信息,它是 DataTransferItem 类型的数据集合数组。DataTransferItem 包含多个属性和方法,属性有 kindtype,方法有 getAsString()getAsFile()

DataTransfer.types(只读)

只读属性,由拖拽内容包含的类型组成的数组,我们可以通过遍历来查看拖拽内容包含的所有类型

DataTransfer 对象方法

DataTransfer.clearData([format])

对给定类型关联的数据进行删除

DataTransfer.getData(format)

返回给定类型的数据,如果该类型的数据不存在或数据传输不包含数据,则返回空字符串

DataTransfer.setData(format, data)

设置给定类型的数据。如果该类型的数据不存在,就在末尾添加。如果该类型的数据已存在,则在相同位置把现有数据替换掉

DataTransfer.setDragImage(img, xOffset, yOffset)

设置用于拖动的自定义图像,就是拖拽时候我们可以自定义一张图片跟在鼠标后面,属于视觉交互。其中img表示自定义图片元素,offsetX 表示距离鼠标的水平偏移距离,offsetY 表示距离鼠标的垂直偏移距离

总结

开始遇到 DataTransfer 时,感觉这个对象神秘又陌生,但其实只要掌握它的几个主要属性,我们就能在绝大多数的场景中熟练使用,实现我们最终想要的效果。

最后,

很感谢你能看到这里,如果你觉得有收获的话,可以给我一个免费的赞哦!

参考

developer.mozilla.org/zh-CN/docs/… www.zhangxinxu.com/wordpress/2…

转载自:https://juejin.cn/post/7134638218074390559
评论
请登录