千家信息网

JavaScript中DataTransfer接口的概述及实例属性

发表于:2024-12-12 作者:千家信息网编辑
千家信息网最后更新 2024年12月12日,这篇文章主要介绍"JavaScript中DataTransfer接口的概述及实例属性",在日常操作中,相信很多人在JavaScript中DataTransfer接口的概述及实例属性问题上存在疑惑,小编
千家信息网最后更新 2024年12月12日JavaScript中DataTransfer接口的概述及实例属性

这篇文章主要介绍"JavaScript中DataTransfer接口的概述及实例属性",在日常操作中,相信很多人在JavaScript中DataTransfer接口的概述及实例属性问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"JavaScript中DataTransfer接口的概述及实例属性"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

目录
  • DragEvent 接口

  • DataTransfer 接口概述

  • DataTransfer 的实例属性

    • DataTransfer.dropEffect

    • DataTransfer.effectAllowed

    • DataTransfer.files

    • DataTransfer.types

    • DataTransfer.items

  • DataTransfer 的实例方法

    • DataTransfer.setData()

    • DataTransfer.getData()

    • DataTransfer.clearData()

    • DataTransfer.setDragImage()

拖拉(drag)指的是,用户在某个对象上按下鼠标键不放,拖动它到另一个位置,然后释放鼠标键,将该对象放在那里。

拖拉的对象有好几种,包括元素节点、图片、链接、选中的文字等等。在网页中,除了元素节点默认不可以拖拉,其他(图片、链接、选中的文字)都是可以直接拖拉的。为了让元素节点可拖拉,可以将该节点的draggable属性设为true

此区域可拖拉

draggable属性可用于任何元素节点,但是图片()和链接()不加这个属性,就可以拖拉。对于它们,用到这个属性的时候,往往是将其设为false,防止拖拉这两种元素。

注意,一旦某个元素节点的draggable属性设为true,就无法再用鼠标选中该节点内部的文字或子节点了。

当元素节点或选中的文本被拖拉时,就会持续触发拖拉事件,包括以下一些事件。

下面的例子展示,如何动态改变被拖动节点的背景色。

div.addEventListener('dragstart', function (e) {  this.style.backgroundColor = 'red';}, false); div.addEventListener('dragend', function (e) {  this.style.backgroundColor = 'green';}, false);

上面代码中,div节点被拖动时,背景色会变为红色,拖动结束,又变回绿色。

下面是一个例子,展示如何实现将一个节点从当前父节点,拖拉到另一个父节点中。

/* HTML 代码如下 
该节点可拖拉
*/ // 被拖拉节点var dragged; document.addEventListener('dragstart', function (event) { // 保存被拖拉节点 dragged = event.target; // 被拖拉节点的背景色变透明 event.target.style.opacity = 0.5;}, false); document.addEventListener('dragend', function (event) { // 被拖拉节点的背景色恢复正常 event.target.style.opacity = '';}, false); document.addEventListener('dragover', function (event) { // 防止拖拉效果被重置,允许被拖拉的节点放入目标节点 event.preventDefault();}, false); document.addEventListener('dragenter', function (event) { // 目标节点的背景色变紫色 // 由于该事件会冒泡,所以要过滤节点 if (event.target.className === 'dropzone') { event.target.style.background = 'purple'; }}, false); document.addEventListener('dragleave', function( event ) { // 目标节点的背景色恢复原样 if (event.target.className === 'dropzone') { event.target.style.background = ''; }}, false); document.addEventListener('drop', function( event ) { // 防止事件默认行为(比如某些元素节点上可以打开链接), event.preventDefault(); if (event.target.className === 'dropzone') { // 恢复目标节点背景色 event.target.style.background = ''; // 将被拖拉节点插入目标节点 dragged[xss_clean].removeChild(dragged); event.target.appendChild( dragged ); }}, false);

关于拖拉事件,有以下几个注意点。

上面代码中,如果不取消拖拉事件或者阻止默认行为,就不能在div节点上放下被拖拉的节点。

DragEvent 接口

拖拉事件都继承了DragEvent接口,这个接口又继承了MouseEvent接口和Event接口。

浏览器原生提供一个DragEvent()构造函数,用来生成拖拉事件的实例对象。

new DragEvent(type, options)

DragEvent()构造函数接受两个参数,第一个参数是字符串,表示事件的类型,该参数必须;第二个参数是事件的配置对象,用来设置事件的属性,该参数可选。配置对象除了接受MouseEvent接口和Event接口的配置属性,还可以设置dataTransfer属性要么是null,要么是一个DataTransfer接口的实例。

DataTransfer的实例对象用来读写拖拉事件中传输的数据,详见下文《DataTransfer 接口》的部分。

DataTransfer 接口概述

所有拖拉事件的实例都有一个DragEvent.dataTransfer属性,用来读写需要传递的数据。这个属性的值是一个DataTransfer接口的实例。

浏览器原生提供一个DataTransfer()构造函数,用来生成DataTransfer实例对象。

var dataTrans = new DataTransfer();

DataTransfer()构造函数不接受参数。

拖拉的数据分成两方面:数据的种类(又称格式)和数据的值。数据的种类是一个 MIME 字符串(比如text/plainimage/jpeg),数据的值是一个字符串。一般来说,如果拖拉一段文本,则数据默认就是那段文本;如果拖拉一个链接,则数据默认就是链接的 URL。

拖拉事件开始时,开发者可以提供数据类型和数据值。拖拉过程中,开发者通过dragenterdragover事件的监听函数,检查数据类型,以确定是否允许放下(drop)被拖拉的对象。比如,在只允许放下链接的区域,检查拖拉的数据类型是否为text/uri-list

发生drop事件时,监听函数取出拖拉的数据,对其进行处理。

DataTransfer 的实例属性

DataTransfer.dropEffect

DataTransfer.dropEffect属性用来设置放下(drop)被拖拉节点时的效果,会影响到拖拉经过相关区域时鼠标的形状。它可能取下面的值。

除了上面这些值,设置其他的值都是无效的。

target.addEventListener('dragover', function (e) {  e.preventDefault();  e.stopPropagation();  e.dataTransfer.dropEffect = 'copy';});

上面代码中,被拖拉元素一旦drop,接受的区域会复制该节点。

dropEffect属性一般在dragenterdragover事件的监听函数中设置,对于dragstartdragdragleave这三个事件,该属性不起作用。因为该属性只对接受被拖拉的节点的区域有效,对被拖拉的节点本身是无效的。进入目标区域后,拖拉行为会初始化成设定的效果。

DataTransfer.effectAllowed

DataTransfer.effectAllowed属性设置本次拖拉中允许的效果。它可能取下面的值。

如果某种效果是不允许的,用户就无法在目标节点中达成这种效果。

这个属性与dropEffect属性是同一件事的两个方面。前者设置被拖拉的节点允许的效果,后者设置接受拖拉的区域的效果,它们往往配合使用。

dragstart事件的监听函数,可以用来设置这个属性。其他事件的监听函数里面设置这个属性是无效的。

source.addEventListener('dragstart', function (e) {  e.dataTransfer.effectAllowed = 'move';}); target.addEventListener('dragover', function (e) {  ev.dataTransfer.dropEffect = 'move';});

只要dropEffect属性和effectAllowed属性之中,有一个为none,就无法在目标节点上完成drop操作。

DataTransfer.files

DataTransfer.files属性是一个 FileList 对象,包含一组本地文件,可以用来在拖拉操作中传送。如果本次拖拉不涉及文件,则该属性为空的 FileList 对象。

下面就是一个接收拖拉文件的例子。

// HTML 代码如下// 
// 文件拖拉到这里//
var div = document.getElementById('output'); div.addEventListener("dragenter", function( event ) { div.textContent = ''; event.stopPropagation(); event.preventDefault();}, false); div.addEventListener("dragover", function( event ) { event.stopPropagation(); event.preventDefault();}, false); div.addEventListener("drop", function( event ) { event.stopPropagation(); event.preventDefault(); var files = event.dataTransfer.files; for (var i = 0; i < files.length; i++) { div.textContent += files[i].name + ' ' + files[i].size + '字节\n'; }}, false);

上面代码中,通过dataTransfer.files属性读取被拖拉的文件的信息。如果想要读取文件内容,就要使用FileReader对象。

div.addEventListener('drop', function(e) {  e.preventDefault();  e.stopPropagation();   var fileList = e.dataTransfer.files;  if (fileList.length > 0) {    var file = fileList[0];    var reader = new FileReader();    reader.onloadend = function(e) {      if (e.target.readyState === FileReader.DONE) {        var content = reader.result;        div[xss_clean] = 'File: ' + file.name + '\n\n' + content;      }    }    reader.readAsBinaryString(file);  }});

DataTransfer.types

DataTransfer.types属性是一个只读的数组,每个成员是一个字符串,里面是拖拉的数据格式(通常是 MIME 值)。比如,如果拖拉的是文字,对应的成员就是text/plain

下面是一个例子,通过检查dataTransfer属性的类型,决定是否允许在当前节点执行drop操作。

function contains(list, value){  for (var i = 0; i < list.length; ++i) {    if(list[i] === value) return true;  }  return false;} function doDragOver(event) {  var isLink = contains(event.dataTransfer.types, 'text/uri-list');  if (isLink) event.preventDefault();}

上面代码中,只有当被拖拉的节点是一个链接时,才允许在当前节点放下。

DataTransfer.items

DataTransfer.items属性返回一个类似数组的只读对象(DataTransferItemList 实例),每个成员就是本次拖拉的一个对象(DataTransferItem 实例)。如果本次拖拉不包含对象,则返回一个空对象。

DataTransferItemList 实例具有以下的属性和方法。

DataTransferItem 实例具有以下的属性和方法。

下面是一个例子。

div.addEventListener('drop', function (e) {  e.preventDefault();  if (e.dataTransfer.items != null) {    for (var i = 0; i < e.dataTransfer.items.length; i++) {      console.log(e.dataTransfer.items[i].kind + ': ' + e.dataTransfer.items[i].type);    }  }});

DataTransfer 的实例方法

DataTransfer.setData()

DataTransfer.setData()方法用来设置拖拉事件所带有的数据。该方法没有返回值。

event.dataTransfer.setData('text/plain', 'Text to drag');

上面代码为当前的拖拉事件加入纯文本数据。

该方法接受两个参数,都是字符串。第一个参数表示数据类型(比如text/plain),第二个参数是具体数据。如果指定类型的数据在dataTransfer属性不存在,那么这些数据将被加入,否则原有的数据将被新数据替换。

如果是拖拉文本框或者拖拉选中的文本,会默认将对应的文本数据,添加到dataTransfer属性,不用手动指定。

上面代码中,拖拉这个

元素会自动带上文本数据aaa

使用setData方法,可以替换到原有数据。

aaa

上面代码中,拖拉数据实际上是bbb,而不是aaa

下面是添加其他类型的数据。由于text/plain是最普遍支持的格式,为了保证兼容性,建议最后总是保存一份纯文本格式的数据。

var dt = event.dataTransfer; // 添加链接dt.setData('text/uri-list', 'http://www.example.com');dt.setData('text/plain', 'http://www.example.com'); // 添加 HTML 代码dt.setData('text/html', 'Hello there, stranger');dt.setData('text/plain', 'Hello there, stranger'); // 添加图像的 URLdt.setData('text/uri-list', imageurl);dt.setData('text/plain', imageurl);

可以一次提供多种格式的数据。

var dt = event.dataTransfer;dt.setData('application/x-bookmark', bookmarkString);dt.setData('text/uri-list', 'http://www.example.com');dt.setData('text/plain', 'http://www.example.com');

上面代码中,通过在同一个事件上面,存放三种类型的数据,使得拖拉事件可以在不同的对象上面,drop不同的值。注意,第一种格式是一个自定义格式,浏览器默认无法读取,这意味着,只有某个部署了特定代码的节点,才可能drop(读取到)这个数据。

DataTransfer.getData()

DataTransfer.getData()方法接受一个字符串(表示数据类型)作为参数,返回事件所带的指定类型的数据(通常是用setData方法添加的数据)。如果指定类型的数据不存在,则返回空字符串。通常只有drop事件触发后,才能取出数据。

下面是一个drop事件的监听函数,用来取出指定类型的数据。

function onDrop(event) {  var data = event.dataTransfer.getData('text/plain');  event.target.textContent = data;  event.preventDefault();}

上面代码取出拖拉事件的文本数据,将其替换成当前节点的文本内容。注意,这时还必须取消浏览器的默认行为,因为假如用户拖拉的是一个链接,浏览器默认会在当前窗口打开这个链接。

getData方法返回的是一个字符串,如果其中包含多项数据,就必须手动解析。

function doDrop(event) {  var lines = event.dataTransfer.getData('text/uri-list').split('\n');  for (let line of lines) {    let link = document.createElement('a');    link.href = line;    link.textContent = line;    event.target.appendChild(link);  }  event.preventDefault();}

上面代码中,getData方法返回的是一组链接,就必须自行解析。

类型值指定为URL,可以取出第一个有效链接。

var link = event.dataTransfer.getData('URL');

下面的例子是从多种类型的数据里面取出数据。

function doDrop(event) {  var types = event.dataTransfer.types;  var supportedTypes = ['text/uri-list', 'text/plain'];  types = supportedTypes.filter(function (value) { types.includes(value) });  if (types.length) {    var data = event.dataTransfer.getData(types[0]);  }  event.preventDefault();}

DataTransfer.clearData()

DataTransfer.clearData()方法接受一个字符串(表示数据类型)作为参数,删除事件所带的指定类型的数据。如果没有指定类型,则删除所有数据。如果指定类型不存在,则调用该方法不会产生任何效果。

event.dataTransfer.clearData('text/uri-list');

上面代码清除事件所带的text/uri-list类型的数据。

该方法不会移除拖拉的文件,因此调用该方法后,DataTransfer.types属性可能依然会返回Files类型(前提是存在文件拖拉)。

注意,该方法只能在dragstart事件的监听函数之中使用,因为这是拖拉操作的数据唯一可写的时机。

DataTransfer.setDragImage()

拖动过程中(dragstart事件触发后),浏览器会显示一张图片跟随鼠标一起移动,表示被拖动的节点。这张图片是自动创造的,通常显示为被拖动节点的外观,不需要自己动手设置。

DataTransfer.setDragImage()方法可以自定义这张图片。它接受三个参数。第一个是节点或者节点,如果省略或为null,则使用被拖动的节点的外观;第二个和第三个参数为鼠标相对于该图片左上角的横坐标和右坐标。

下面是一个例子。

/* HTML 代码如下 
drag me
*/ var div = document.getElementById('drag-with-image');div.addEventListener('dragstart', function (e) { var img = document.createElement('img'); img.src = 'http://path/to/img'; e.dataTransfer.setDragImage(img, 0, 0);}, false);

到此,关于"JavaScript中DataTransfer接口的概述及实例属性"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0