• HTML5 Drag & Drop


    简介

    HTML5 Drag & Drop 是一组定义拖放行为的API,如果你想开发在线Excel之类富交互的应用,它应该能帮你节省不少时间。

    拖放过程由两个部分构成:

    • 被拖拽的元素,之后简称为子项(item)

    • 放置被拖拽元素的元素,之后简称为容器(container)

    快速示例

    一个将子项拖进容器的简单功能,CSS略过,以jQuery操作DOM:

    图片描述

      <div id="container"></div>
      <div id="item" draggable></div>
      $('#container').on('dragover', function(e){
        e.preventDefault()
      })
      
      $('#container').on('drop', function(e){
        $('#item').appendTo(this)
      })

    首先在子项上添加draggable属性,表明元素可以被拖拽(发觉在Chrome中不加也可以。)

    容器的dragover事件必须禁止默认事件,否则这个容器不允许放置子项。

    容器的drop事件在子项放置到容器后触发。

    可以看到,这组API只会提供简单的行为与事件接口,拖放后会发生什么,还是得由我们自己来实现。

    事件

    子项事件

    • dragstart - 拖拽开始

    • drag - 拖拽过程中不断触发

    • dragend - 拖拽结束,无论有没有拖进容器( 鼠标松开就触发 )

    这3个事件与touch系列事件很相似。

    容器事件

    • dragenter - 子项进入容器范围

    • dragover - 子项在容器范围内不断触发

    • dragleave - 子项离开容器范围

    • drop - 拖拽结束,且子项成功拖进容器

    前3个事件与mouse系列事件很相似。

    注意,放开鼠标时,无论子项有没有拖进容器,都一定会触发子项的dragend事件,表示拖拽行为的完结;而只有成功拖进容器,才会触发容器的drop事件,表示确实落地了。

    DataTransfer

    dataTransfer是这组API的核心对象,提供了许多实用功能。

    传递数据

    dataTransfer可以传递数据:

      $('#item').on('dragstart', function(e){
        e.originalEvent.dataTransfer.setData('name', 'kid')
        e.originalEvent.dataTransfer.setData('age', 18)
      })
      $('#container').on('dragover', function(e){
        e.preventDefault()
      })
      $('#container').on('drop', function(e){
        e.originalEvent.dataTransfer.getData('NAME')  // => 'kid'
        e.originalEvent.dataTransfer.getData('age')   // => '18'
      })

    因为这里使用了jQuery,所以是e.originalEvent.dataTransfer,若用原生方式绑定事件,则为e.dataTransfer

    key不区分大小写,所以'name'中的值,用'NAME'也能取出来。若key不存在,则返回空字符串。

    value一律转换为字符串,所以数字age存的是数字,但取出来是字符串。

    keyURL时,若value为一个合法的url值(比如'http://www.baidu.com'),则拖拽到浏览器地址栏或标签栏会打开对应页面。

    clearData可以清除数据,但只能在dragstart中进行,用处不大:

      $('#item').on('dragstart', function(e){
        e.originalEvent.dataTransfer.setData('name', 'kid')
        e.originalEvent.dataTransfer.setData('age', 18)
        e.originalEvent.dataTransfer.clearData('name')  // 若不指定key,则清除所有数据
      })
      $('#container').on('dragover', function(e){
        e.preventDefault()
      })
      $('#container').on('drop', function(e){
        var a = e.originalEvent.dataTransfer.getData('NAME')  // => ''
        var b = e.originalEvent.dataTransfer.getData('age')   // => '18'
      })

    effectAllowed / dropEffect

    容器可以用dataTransfer.dropEffect设置一个类型,它指示了进入本容器的子项会发生什么效果:

    • move - 移动子项到容器

    • copy - 复制子项到容器

    • link - 打开链接

    • none - 禁止任何子项放置在此容器

    这个效果不会自动发生。试一试就知道了,当子项拖入容器范围,则鼠标指针会变成相应类型的外观(由浏览器设定)。这是针对用户的简单提示,而不是说设置为copy就会自动复制子项。还是那句话,由你来具体实现。

    与此对应,子项通过dataTransfer.effectAllowed属性可限定自己着陆的容器类型:

    • move

    • copy

    • link

    • copyMove - copymove

    • copyLink - copylink

    • linkMove - linkmove

    • all - movecopylink

    • uninitialized - 默认值,等价于all

    • none - 禁止在任何容器着陆

    实际使用看看:

      $('#item').on('dragstart', function(e){
        e.originalEvent.dataTransfer.effectAllowed = 'all'
      })
      $('#container').on('dragover', function(e){
        e.preventDefault()
      })
      $('#container').on('drop', function(e){
        e.originalEvent.dataTransfer.dropEffect = 'copy'
      })

    若两者不匹配,则子项无法放置到容器中。

    过渡图片

    在相册类应用中,拖拽照片是一个常见功能。我们可以用setDragImage方法来设置一张图片,在拖拽过程中跟随鼠标移动:

      var img = new Image()
      img.src = 'face-small.png'
    
      $('#item').on('dragstart', function(e){
        e.originalEvent.dataTransfer.setDragImage(img, 100, 100)
      })

    第一个参数设置图片,后两个参数设置鼠标相对图片的位置。比如这张图的大小是200×200,我设置100表示鼠标在图片正中心,效果示意:

    图片描述

    另外,setDragImage也可以接收Canvas图像,简单示例:

      <canvas width="200", height="200"></canvas>
      var canvas = $('canvas')[0]
      var ctx = canvas.getContext('2d')
      ctx.fillStyle="pink"
      ctx.fillRect(0, 0, 200, 200)
    
      $('#item').on('dragstart', function(e){
        e.originalEvent.dataTransfer.setDragImage(canvas, 100, 100)
      })

    兼容性

    最后说一下,这组API现在基本只能用于PC端:

    图片描述

    原创,自由转载,请署名,本人博客 kid-wumeng.me

  • 相关阅读:
    前端+php实现概率抽奖
    rem.js的用法及在浏览器端的适配
    python 使用记录及问题
    python 工具链 虚拟环境和包管理工具 pipenv
    python 工具链 多版本管理工具 pyenv
    python 工具链 包管理工具 pip
    ansible 使用记录
    mongodb connection refused because too many open connections: 819
    wordpress 常用操作
    服务器硬件测试
  • 原文地址:https://www.cnblogs.com/10manongit/p/12654129.html
Copyright © 2020-2023  润新知