1、拖放效果
2、draggable屬性
如果網頁元素的draggable元素為true,這個元素就是可以拖動的。
<div draggable="true">Draggable Div</div>
在大多數瀏覽器中,a元素和img元素默認就是可以拖放的,但是為了保險起見,最好還是加上draggable屬性。
3、事件
拖動過程會觸發很多事件,主要有下面這些:
- dragstart:網頁元素開始拖動時觸發。
- drag:被拖動的元素在拖動過程中持續觸發。
- dragenter:被拖動的元素進入目標元素時觸發,應在目標元素監聽該事件。
- dragleave:被拖動的元素離開目標元素時觸發,應在目標元素監聽該事件。
- dragover:被拖動元素停留在目標元素之中時持續觸發,應在目標元素監聽該事件。
- drap:被拖動元素或從文件系統選中的文件,拖放落下時觸發。
- dragend:網頁元素拖動結束時觸發。
以上這些事件都可以指定回調函數。下面就是一個回調函數的例子。
draggableElement.addEventListener('dragstart', function(e) { console.log('拖動開始!'); });
上面的代碼在網頁元素被拖動時,在控制台顯示“拖動開始!”。
注:在拖動過程中,鼠標移動事件不會觸發。
4、dataTransfer對象
拖動過程中,回調函數接受的事件參數,有一個dataTransfer屬性。它指向一個對象,包含了與拖動相關的各種信息。
draggableElement.addEventListener('dragstart', function(event) { event.dataTransfer.setData('text', 'Hello World!'); });
上面代碼在拖動開始時,在dataTransfer對象上儲存一條文本信息,內容為“Hello World”。當拖放結束時,可以用getData方法取出這條信息。
dataTransfer對象的屬性:
- dropEffect:拖放的操作類型,決定了瀏覽器如何顯示鼠標形狀,可能的值為copy、move、link和none。
- effectAllowed:指定所允許的操作,可能的值為copy、move、link、copyLink、copyMove、linkMove、all、none和uninitialized(默認值,等同於all,即允許一切操作)。
- files:包含一個FileList對象,表示拖放所涉及的文件,主要用於處理從文件系統拖入瀏覽器的文件。
- types:儲存在DataTransfer對象的數據的類型。
dataTransfer對象的方法:
- setData(format, data):在dataTransfer對象上儲存數據。第一個參數format用來指定儲存的數據類型,比如text、url、text/html等。
- getData(format):從dataTransfer對象取出數據。
- clearData(format):清除dataTransfer對象所儲存的數據。如果指定了format參數,則只清除該格式的數據,否則清除所有數據。
- setDragImage(imgElement, x, y):指定拖動過程中顯示的圖像。默認情況下,許多瀏覽器顯示一個被拖動元素的半透明版本。參數imgElement必須是一個圖像元素,而不是指向圖像的路徑,參數x和y表示圖像相對於鼠標的位置。
dataTransfer對象允許在其上存儲數據,這使得在被拖動元素與目標元素之間傳送信息成為可能。
5、實例:拖動網元素
首先,獲取網頁元素。
var target = document.querySelector('#drop-target'); var dragElements = document.querySelectorAll('#drag-elements li'); // 追蹤被拖動元素的變量 var elementDragged = null;
上面的代碼在獲取目標元素和可能的被拖動元素后,新建了一個變量elementDragged,用來存放實際拖動的元素。
然后,對可能的被拖動元素綁定dragstart事件和dragend事件。
for (var i = 0; i < dragElements.length; i++) { dragElements[i].addEventListener('dragstart', function(e) { e.dataTransfer.setData('text', this.innerHTML); elementDragged = this; }); dragElements[i].addEventListener('dragend', function(e) { elementDragged = null; }); };
接着綁定目標元素的dragover事件,主要是為了當被拖動元素進入目標元素后,改變鼠標形狀。
target.addEventListener('dragover', function(e) { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; return false; });
最后,定義目標元素的drop事件,處理被拖動元素(從原來的位置刪除)。
target.addEventListener('drop', function(e) { e.preventDefault(); e.stopPropagation(); this.innerHTML = "Dropped " + e.dataTransfer.getData('text'); document.querySelector('#drag-elements').removeChild(elementDragged); return false; });
6、實例:拖放文件
假定我們要從文件系統拖動一個txt文本,在瀏覽器中展示內容。
首先,獲取拖動的目標元素和內容展示區域。
var target = document.querySelector('#target'); var contentDiv = document.querySelector('#content');
然后,定義目標元素的dragover事件,主要是為了當文件進入目標元素后,改變鼠標形狀。
target.addEventListener('dragover', function(e) { e.preventDefault(); e.stopPropagation(); e.dataTransfer.dropEffect = 'copy'; });
接着,定義目標元素的drop事件,展示文件內容。
target.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; contentDiv.innerHTML = "File: " + file.name + "\n\n" + content; } } reader.readAsBinaryString(file); } });
7、參考鏈接
[1] Matt West, Implementing Native Drag and Drop
注:本文轉自http://javascript.ruanyifeng.com/dom/dragndrop.html,有修改。