2、基於HTML5拖拽API的拖拽
前序知識介紹
一個典型的拖拽操做是這樣的:用戶用鼠標選中一個可拖動的(draggable)元素,移動鼠標到一個可放置的(droppable)元素,而後釋放鼠標。 在操做期間,會觸發一些事件類型,有一些事件類型可能會被屢次觸發(好比drag 和 dragover 事件類型)。css
一個完整的drag and drop流程一般包含如下幾個步驟:html
draggable="true"
實現元素的可拖拽.dragstart
設置拖拽數據copy
,move
,link
dragenter
或者dragover
取消瀏覽器默認行爲使元素可拖放.drop
事件執行所需操做
這裏涉及幾個知識點:web
一、可拖動元素:又稱爲源對象,是指咱們鼠標點擊以後準備拖動的對象(圖片、div、文字等)
二、可放置元素:又稱爲目標對象,是指能夠放置源對象的區域瀏覽器
三、事件:app
Event | On Event Handler | Description |
---|---|---|
drag | ondrag | 當拖動元素或選中的文本時觸發 |
dragend | ondragend | 當拖拽操做結束時觸發 (好比鬆開鼠標按鍵或敲「Esc」鍵) |
dragenter | ondragenter | 當拖動元素或選中的文本到一個可釋放目標時觸發 |
dragexit | ondragexit | 當元素變得再也不是拖動操做的選中目標時觸發 |
dragleave | ondragleave | 當拖動元素或選中的文本離開一個可釋放目標時觸發 |
dragover | ondragover | 當元素或選中的文本被拖到一個可釋放目標上時觸發 |
dragstart | ondragstart | 當用戶開始拖動一個元素或選中的文本時觸發 |
drop | ondrop | 當元素或選中的文本在可釋放目標上被釋放時觸發 |
ps:當從操做系統向瀏覽器中拖動文件時,不會觸發dragstart 和dragend 事件ide
四、接口:函數
HTML5爲全部的拖動相關事件提供了一個新的屬性:this
屬性和方法 |
描述 |
dropEffect | 拖拽交互類型,一般決定瀏覽器如何顯示鼠標光標並控制拖放操做.常見的取值有copy ,move ,link 和none |
effectAllowed | 指定容許的交互類型,能夠取值:copy ,move ,link ,copyLink ,copyMove ,limkMove , all , none 默認爲uninitialized (容許全部操做) |
files | 包含File 對象的FileList 對象.從操做系統向瀏覽器拖放文件時有用. |
types | 保存DataTransfer 對象中設置的全部數據類型. |
setData(format, data) | 以鍵值對設置數據,format一般爲數據格式,如text ,text/html |
getData(format) | 獲取設置的對應格式數據,format與setData()中一致 |
clearData(format) | 清除指定格式的數據 |
setDragImage(imgElement, x, y) | 設置自定義圖標 |
源對象和目標對象的事件間傳遞數據spa
event.dataTransfer {}//數據傳遞對象
源對象上的事件處理中保存數據:操作系統
event.dataTransfer.setData(key,value);//key,value必須都是字符串類型
如:
event.dataTransfer.setData("text/plain", "This is text to drag");
目標對象上的事件處理中讀取數據:
var value2 = event.dataTransfer.getData(key);
demo
<div id="demo1"> <ul class="panel-list"> <li class="panel-item"></li> <li class="panel-item"></li> <li class="panel-item"></li> <li class="panel-item"></li> <li class="panel-item"></li> </ul> <h2>拖拽下面的方塊到上面任意容器中</h2> <!-- 設置draggable使元素成爲可拖拽元素 --> <div class="movable" id="demo1-src" draggable="true" draggable="true"> <img style="width:100%;" src="__ADMIN__/img/pbl/11.jpg"> </div> <style> #demo1 { margin: 20px; } #demo1 .panel-list { overflow: hidden; list-style: none; margin: 0; padding: 0; } #demo1 .panel-item { float: left; margin-right: 30px; width: 100px; height: 100px; background: #ddd; border: 1px solid #ddd; } #demo1-src { display: inline-block; width: 50px; height: 50px; background: purple; } #demo1 .over { border: 1px dashed #000; -webkit-transform: scale(0.8, 0.8); } </style> <script> (function () { var dnd = { // 初始化 init: function () { var me = this; me.src = document.querySelector('#demo1-src');//獲取指定css選擇器的元素 me.panelList = document.querySelector('.panel-list');//獲取指定css選擇器的元素 console.log( me.panelList ); //addEventListener('要監聽的事件名','事件觸發的函數',布爾:指定事件是否在捕獲或冒泡階段執行) // 爲拖拽源監聽dragstart,設置關聯數據 me.src.addEventListener('dragstart', me.onDragStart, false); // 拖拽鼠標移入元素,在拖放目標上設置視覺反饋 me.panelList.addEventListener('dragenter', me.onDragEnter, false); // 取消元素dragover默認行爲,使其可拖放 me.panelList.addEventListener('dragover', me.onDragOver, false); // 拖拽移出元素,清除視覺反饋 me.panelList.addEventListener('dragleave', me.onDragLeave, false); // 鼠標釋放,在拖放目標上接收數據並處理 me.panelList.addEventListener('drop', me.onDrop, false); }, onDragStart: function (e) { //setData(format, data) 以鍵值對設置數據,format一般爲數據格式,如text,text/html //設置可拖動元素的id(存起來) e.dataTransfer.setData('text/plain', 'demo1-src'); e.target.style.height="100px"; e.target.style.cursor="move"; }, //當拖動元素或選中的文本到一個可釋放目標時觸發 onDragEnter: function (e) { console.log(e.target); //e.target : <ul class="panel-list"></ul> //panel-list元素的子元素的類名列表中包含panel-item類則添加over類(呈現虛框效果) if (e.target.classList.contains('panel-item')) { //爲panel-item的元素添加over類 e.target.classList.add('over'); } }, //當拖動元素或選中的文本離開一個可釋放目標時觸發(移除over類) onDragLeave: function (e) { e.target.style.cursor="move"; if (e.target.classList.contains('panel-item')) { e.target.classList.remove('over'); } }, //當元素或選中的文本被拖到一個可釋放目標上時觸發(取消事件的默認動做好比說表單自動提交) onDragOver: function (e) { e.preventDefault(); }, //當元素或選中的文本在可釋放目標上被釋放時觸發 onDrop: function (e) { var id = e.dataTransfer.getData('text/plain'); var src = document.getElementById(id); var target = e.target; if (target.classList.contains('panel-item')) { target.appendChild(src); target.classList.remove('over'); } } }; dnd.init(); }()); </script> </div> <div id="demo2"> <h3>從文件夾中拖拽圖片到下面的區域進行預覽</h3> <ul class="preview"></ul> <style> #demo2 { margin: 20px; } #demo2 .preview { height: 300px; background: #ddd; } #demo2 li { float: left; margin-left: 40px; } #demo2 img { max-height: 150px; width: auto; } </style> <script> (function (w) { var doc = w.document; var dnd = { init: function () { var me = this; var preview = doc.querySelector('#demo2 .preview'); preview.addEventListener('dragover', function (e) { e.preventDefault(); }, false); preview.addEventListener('drop', function (e) { // 操做系統拖放文件到瀏覽器須要取消默認行爲 e.preventDefault(); [].forEach.call(e.dataTransfer.files, function (file) { if (file && file.type.match('image.*')) { var reader = new FileReader(); reader.onload = function (e) { var img = doc.createElement('img'); img.src = e.target.result; var li = doc.createElement('li'); li.appendChild(img); preview.appendChild(li); }; reader.readAsDataURL(file); } }); }, false); } }; dnd.init(); }(window)); </script> </div> <!-- demo2 -->