zlx362211854 / daily-study

每日一个知识点总结,以issue的形式体现
10 stars 6 forks source link

14. 介绍一下DataTransfer对象 #33

Open zlx362211854 opened 5 years ago

zlx362211854 commented 5 years ago

1.元素的可拖拽属性

html5中增加了元素拖拽的支持,只需要增加一个属性draggable:true后,元素就被赋予了可拖拽的能力。

当元素可拖拽后,可给元素添加6类拖拽事件监听:

如下,实现一个拖拽元素:

 <div id='test'>Drag the file here</div>
   var dom = document.getElementById('test');
    dom.setAttribute('draggable', 'true'); // 使元素可拖拽
    dom.addEventListener('dragstart', function (event) {
      console.log('dragstart: ' + event.dataTransfer); 
    });

3. DataTransfer的属性和方法

DataTransfer对象包含下面5个标准属性和4个标准方法。

标准属性

DataTransfer.dropEffect 获取当前所选拖放操作的类型,或将拖拽操作设置为新类型。值必须为none,copy,link或move中的一个。 DataTransfer.effectAllowed 提供可能的所有类型的操作。必须是none,copy,copyLink,copyMove,link,linkMove,move,all或uninitialized中的一个。 DataTransfer.files 拖拽的本地文件列表。如果拖动操作不涉及拖动文件,则此属性为空列表。 DataTransfer.items (只读) 提供DataTransferItemList对象,该对象是所有拖动数据的列表。 DataTransfer.types(只读) 在dragstart事件中设置数据格式,返回的是一个字符串数组。

标准方法

DataTransfer.clearData([format]) 删除与给定类型关联的数据。format参数是可选的。如果类型为空或未指定,则删除所有关联的数据。如果指定类型的数据不存在,或者数据传输不包含任何数据,则此方法无效。 DataTransfer.getData(format) 返回给定类型的数据,如果该类型的数据不存在或数据传输不包含数据,则返回空字符串。 DataTransfer.setData(format, data) 设置给定类型的数据。如果该类型的数据不存在,则在末尾添加,以使列表中的最后一项成为新格式类型。如果该类型的数据已存在,则在相同位置把现有数据替换掉。 DataTransfer.setDragImage(img, xOffset, yOffset) 设置用于拖动的自定义图像。

下面用元素拖拽实现一个拖拽上传的demo:

 <div id='test'>Drag the file here</div>
document.addEventListener('drop', function (e) {
      e.preventDefault()
    }, false)
    document.addEventListener('dragover', function (e) {
      e.preventDefault()
    }, false)
    var dom = document.getElementById('test');
    dom.setAttribute('draggable', 'true');
    dom.addEventListener('drop', function (event) {
        console.log('drop: ' + event.dataTransfer);   
        var files = event.dataTransfer.files || [];  
        if (files[0]) {
          upload(files[0], dom)
        }
    });
var upload = function(file, dom) {
      var formData = new FormData();
      formData.append('file', file);
      // ajax上传
      var xhr = null;
      if (window.XMLHttpRequest){
        xhr=new XMLHttpRequest();
      }else{
        xhr=new ActiveXObject("Microsoft.XMLHTTP");
      }
      // 上传结束 
      xhr.onload = function () {
        var result = JSON.parse(xhr.responseText);
         console.log(result, 'result')
        if (result.code === 1000) {
          alert('上传成功')
          dom.innerText = file.name
        }
      };
      xhr.open('POST', 'http://localhost:3060/file/uploadAvatar', true); 
      xhr.send(formData);
    }

upload4

demo代码仓库

用拖拽实现一个拖拽列表功能:

drag

demo代码仓库

goldEli commented 5 years ago

dataTransfer 从字面理解,很直观就知道是用来传递数据的。为浏览器的 DragDrop 事件传递数据。

用一个例子来说明,假如我们有个 li 组成的水果列表,每个 li 都可以拖动,把你喜欢的水果拖到指定区域,代码如下:

<p>What fruits do you like?</p>
<ul id="dragingArea">
  <li id="apple" draggable="true" >apple</li>
  <li id="banana" draggable="true" >banana</li>
  <li id="orange" draggable="true" >orange</li>
</ul>
<p>Drop your favorite fruits below:</p>
<ul
  style="border: 1px solid red;height: 200px; width: 200px;"
  id="dropingArea"
></ul>
<script>
  var internalDNDType = "text/plain"; // set this to something specific to your site
  var dragingArea = document.getElementById("dragingArea");
  var dropingArea = document.getElementById("dropingArea");

  dragingArea.addEventListener("dragstart", event => {
    console.log('dragstart: ', event.target.id);
    event.dataTransfer.setData(internalDNDType, event.target.id);
    // event.dataTransfer.dropEffect = 'copy';
  });

  dropingArea.addEventListener("dragover", event => {
    event.preventDefault()
  })

  dropingArea.addEventListener("drop", event => {
    var data = event.dataTransfer.getData(internalDNDType)
    event.target.append(document.getElementById(data))
    console.log('drop', data)
  })
</script>

总结:

Reference

roxy0724 commented 5 years ago

DataTransfer是在进行拖放操作时,用来保存拖放动作,拖到浏览器的数据的对象。它可以保存一项或多项数据,一种或多种数据类型。最基础的应用就是getDatasetData

document.getElementById('source').ondragstart = function(event) {
    event.dataTransfer.setData('key','value')
}
document.getElementById('target').ondrop = function(event) {
    event.preventDefault()
    const value = event.dataTransfer.getData('key')
}