把文件從桌面拖拽到瀏覽器是Web應(yīng)用程序集成的最終目標之一。本教程共四篇文章(本文是第一篇),主要介紹了:
公司主營業(yè)務(wù):成都網(wǎng)站設(shè)計、成都網(wǎng)站制作、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出樺南免費做網(wǎng)站回饋大家。
1.實現(xiàn)將文件拖放到頁面元素上
2.在JavaScript中分析被拖放的文件
3.在客戶端上加載和解析文件
4.使用XMLHttpRequest2將文件異步上傳到服務(wù)器
5.上傳時,顯示圖形進度條
6.使用進程增強( progressive enhancement)以確保文件上傳表單在所有瀏覽器正常工作
7.純JavaScript代碼,不使用其它庫。
咻,開始吧!
糟糕的瀏覽器支持
在開始之前說明一下,這個教程使用了一些HTML5的最新技術(shù),可能以后會被修正。目前代碼可以正常工作,但是很可能隨著API的變化或者瀏覽器升級而受到影響。
§Firefox和Chrome的最新版本支持所有的功能并且可以完美運行。
§Opera可以用JavaScript解析文件,但未實現(xiàn)拖放文件和XMLHttpRequest2上傳。
§IE瀏覽器和桌面版本的Safari不支持所有的API。
§蘋果已禁用Safari瀏覽器的iPhone和iPad版本的HTML文件上傳表單。有誰知道為什么嗎?
最后,請注意我的代碼只是演示了基本概念,幾乎沒有錯誤檢查,因此需要進行修改以適應(yīng)你的工作需要。
HTML和CSS
這是我們的帶有文件輸入類型的標準表單。唯一的HTML5特性是“multiple”屬性,它允許用戶選擇任意數(shù)量的文件。
我們將上傳文件到運行PHP的服務(wù)器上,但是無論你在服務(wù)器端使用什么技術(shù),代碼是大致相同的。隱藏的MAX_FILE_SIZE值指定為300,000個字節(jié),這是PHP使用的,但我們還會在瀏覽器端用它進行檢查,以防止大文件上傳。
#filedrag元素將被用作接收拖放文件的位置。元素是通過CSS隱藏的,但如果瀏覽器支持拖拽的話,它會在JavaScript中被顯示:
我們還定義了一個.hover類,當(dāng)用戶拖動文件到相應(yīng)區(qū)域元素時,改變元素的顯示風(fēng)格。瀏覽器不支持在那種情況下的:hover風(fēng)格,但當(dāng)事件觸發(fā)時,我們可以用JavaScript添加類。
文件操作API
W3C 文件操作API
提供了一些對象,我們使用了:
§FileList:代表選定的文件數(shù)組。
§File:代表一個單獨的文件。
§FileReader:支持JavaScript的客戶端讀取文件數(shù)據(jù)的接口。
Javascript事件
是時候處理JavaScript代碼了。我們不使用任何JavaScript庫,為了節(jié)省時間,我們將創(chuàng)建一個輔助函數(shù)返回元素的ID和輸出狀態(tài)消息:
我們將在Init()函數(shù)里檢查文件操作API是否有效:
Init()函數(shù)說明:
1.給文件輸入元素設(shè)置一個“change”事件監(jiān)聽器。
2.顯示#filedrag元素。
3.設(shè)置“dragover”和“dragleave”事件監(jiān)聽器,以改變的#filedrag元素的風(fēng)格。
4.給#filedrag元素設(shè)置一個“drop”的事件監(jiān)聽器。
5.隱藏表單的提交按鈕 - 它不是必需的,因為當(dāng)文件被選中時我們將進行分析和上傳,而不是提交表單。
或者,當(dāng)瀏覽器支持文件拖動時,你可以隱藏文件輸入元素。就個人而言,我更愿意同時提供兩種選擇,因為拖放實際上會帶來實用性的問題。
XMLHttpRequest.upload方法檢查防止在Opera中的問題。瀏覽器支持File,F(xiàn)ileList和FileReader,但不支持拖放事件或XMLHttpRequest2。因此,它可以顯示文件信息,但我們不希望顯示#filedrag的元素或刪除submit按鈕。
改變文件拖放風(fēng)格
很少人在瀏覽器中進行過文件拖放。事實上,經(jīng)驗豐富的網(wǎng)絡(luò)用戶也不太考慮是否可行。因此,我們使用了標有“drop files here”的元素。當(dāng)文件拖到#filedrag上時,我們還通過改變元素的風(fēng)格來進行顯示。
分析放下或被選中的文件
無論是使用“Browse”按鈕來選中一個或多個文件,或者將文件拖放到拖#filedrag的位置上,我們使用的的相同F(xiàn)ileSelectHandler()函數(shù)來進行處理:
函數(shù)說明:
1.調(diào)用FileDragHover()刪除hover風(fēng)格和取消瀏覽器的事件。這是必不可少的,否則瀏覽器可能會嘗試顯示該文件。
2.獲取一個FileList對象,無論是從文件輸入框(e.target.files)或#filedrag元素(例如dataTransfer.files)。
3.最后,函數(shù)遍歷FileList的所有File對象,并把它作為一個參數(shù)傳遞給ParseFile()函數(shù)...
該函數(shù)輸出的信息是File對象提供的三個主要的只讀屬性:
§.name: 文件名 (不包含文件路徑)。
§.type: MIME類型, 例如 image/jpeg,text/plain等等。
§.size: 文件大小(字節(jié)).
這是一個網(wǎng)友的代碼 你可以參考一下
!doctype html
html
head
meta charset="utf-8"
title無標題文檔/title
/head
script
function mstart(a){
//設(shè)置初始數(shù)據(jù)setdata()
a.dataTransfer.setData("Text",a.target.id);
}
function mover(a){
//把系統(tǒng)默認鼠標或拖拽操作屏蔽掉
a.preventDefault();//屏蔽系統(tǒng)默認的dragover引發(fā)的效果
}
function mdrop(a){
a.preventDefault();
var data=a.dataTransfer.getData("Text");
a.target.appendChild(document.getElementById(data));
}
/script
body
div id="mydiv" style="height:568px; width:500px; border:2px solid" ondragover="mover(event)" ondrop="mdrop(event)"/div
img id="myimg1" src="vt.jpg" width="250" height="200" draggable="true" ondragstart="mstart(event)"
img id="myimg2" src="vt.jpg" width="250" height="200" draggable="true" ondragstart="mstart(event)"
img id="myimg3" src="vt.jpg" width="250" height="200" draggable="true" ondragstart="mstart(event)"
br
/body
/html
HTML 5 拖放
HTML5 音頻
HTML5 畫布
拖放(Drag 和 drop)是 HTML5 標準的組成部分。
拖放
拖放是一種常見的特性,即抓取對象以后拖到另一個位置。
在 HTML5 中,拖放是標準的一部分,任何元素都能夠拖放。
瀏覽器支持
Internet Explorer 9、Firefox、Opera 12、Chrome 以及 Safari 5 支持拖放。
注釋:在 Safari 5.1.2 中不支持拖放。
HTML5 拖放實例
下面的例子是一個簡單的拖放實例:
實例
!DOCTYPE HTML
html
head
script type="text/javascript"
function allowDrop(ev)
{
ev.preventDefault();
}
function drag(ev)
{
ev.dataTransfer.setData("Text",ev.target.id);
}
function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
/script
/head
body
div id="div1" ondrop="drop(event)"
ondragover="allowDrop(event)"/div
img id="drag1" src="img_logo.gif" draggable="true"
ondragstart="drag(event)" width="336" height="69" /
/body
/html
親自試一試
它看上去也許有些復(fù)雜,不過我們可以分別研究拖放事件的不同部分。
設(shè)置元素為可拖放
首先,為了使元素可拖動,把 draggable 屬性設(shè)置為 true :
img draggable="true" /
拖動什么 - ondragstart 和 setData()
然后,規(guī)定當(dāng)元素被拖動時,會發(fā)生什么。
在上面的例子中,ondragstart 屬性調(diào)用了一個函數(shù),drag(event),它規(guī)定了被拖動的數(shù)據(jù)。
dataTransfer.setData() 方法設(shè)置被拖數(shù)據(jù)的數(shù)據(jù)類型和值:
function drag(ev)
{
ev.dataTransfer.setData("Text",ev.target.id);
}
在這個例子中,數(shù)據(jù)類型是 "Text",值是可拖動元素的 id ("drag1")。
放到何處 - ondragover
ondragover 事件規(guī)定在何處放置被拖動的數(shù)據(jù)。
默認地,無法將數(shù)據(jù)/元素放置到其他元素中。如果需要設(shè)置允許放置,我們必須阻止對元素的默認處理方式。
這要通過調(diào)用 ondragover 事件的 event.preventDefault() 方法:
event.preventDefault()
進行放置 - ondrop
當(dāng)放置被拖數(shù)據(jù)時,會發(fā)生 drop 事件。
在上面的例子中,ondrop 屬性調(diào)用了一個函數(shù),drop(event):
function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
代碼解釋:
調(diào)用 preventDefault() 來避免瀏覽器對數(shù)據(jù)的默認處理(drop 事件的默認行為是以鏈接形式打開)
通過 dataTransfer.getData("Text") 方法獲得被拖的數(shù)據(jù)。該方法將返回在 setData() 方法中設(shè)置為相同類型的任何數(shù)據(jù)。
被拖數(shù)據(jù)是被拖元素的 id ("drag1")
把被拖元素追加到放置元素(目標元素)中
在拖放的過程中會觸發(fā)以下事件:
在拖動目標上觸發(fā)事件 (源元素)
ondragstart?- 用戶開始拖動元素時觸發(fā)
ondrag?- 元素正在拖動時觸發(fā)
ondragend?- 用戶完成元素拖動后觸發(fā)
釋放目標時觸發(fā)的事件
ondragenter?- 當(dāng)被鼠標拖動的對象進入其容器范圍內(nèi)時觸發(fā)此事件
ondragover?- 當(dāng)某被拖動的對象在另一對象容器范圍內(nèi)拖動時觸發(fā)此事件
ondragleave?- 當(dāng)被鼠標拖動的對象離開其容器范圍內(nèi)時觸發(fā)此事件
ondrop?- 在一個拖動過程中,釋放鼠標鍵時觸發(fā)此事件
event對象(以e代替)
e.target
W3Cschool上的解釋是:返回觸發(fā)此事件的元素(事件的目標節(jié)點),這個target屬性只兼容ie9及以上
e.preventDefault()
取消事件的默認動作。
e.dataTransfer.setData()
設(shè)置被拖數(shù)據(jù)的數(shù)據(jù)類型和值。
e.dataTransfer.getData()
獲得被拖的數(shù)據(jù)。
html5 拖動效果在手機上實現(xiàn)方法是調(diào)用drag和drop一系列函數(shù)實現(xiàn)的。
注意:拖拽源在拖拽操作結(jié)束將得到dragend事件對象,不管操作成功與否。
舉例:
定義可拖放內(nèi)容
div id="columns"
div class="column" draggable="true"headerA/header/div
div class="column" draggable="true"headerB/header/div
div class="column" draggable="true"headerC/header/div
/div
2、監(jiān)聽拖動事件
可附加大量不同事件以監(jiān)聽整個拖放過程:
dragstart
drag
dragenter
dragleave
dragover
drop
dragend
a.這里是開始拖拽
function handleDragStart(e) {
this.style.opacity = '0.4'; ?// this / e.target is the source node.
}
var cols = document.querySelectorAll('#columns .column');
[].forEach.call(cols, function(col) {
col.addEventListener('dragstart', handleDragStart, false);
});
b.dragenter、dragover?和?dragleave?事件處理程序可用于在拖動過程中提供額外的可視化提示。例如,在拖動期間將鼠標懸停在某一列上方時,其邊框可能會變成虛線。這樣,用戶就能知道這些列也是放置的目標區(qū)域。