HTML5 Drag & Drop

簡介

HTML5 Drag & Drop 是一組定義拖放行爲的API,若是你想開發在線Excel之類富交互的應用,它應該能幫你節省很多時間。html

拖放過程由兩個部分構成:canvas

  • 被拖拽的元素,以後簡稱爲子項(item)瀏覽器

  • 放置被拖拽元素的元素,以後簡稱爲容器(container)app

快速示例

一個將子項拖進容器的簡單功能,CSS略過,以jQuery操做DOM:this

圖片描述

<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中不加也能夠。)url

容器的dragover事件必須禁止默認事件,不然這個容器不容許放置子項。spa

容器的drop事件在子項放置到容器後觸發。指針

能夠看到,這組API只會提供簡單的行爲與事件接口,拖放後會發生什麼,仍是得由咱們本身來實現。code

事件

子項事件

  • dragstart - 拖拽開始htm

  • 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

相關文章
相關標籤/搜索