拖曳(Drag/Drop)是個非常普遍的功能。你可以抓住一個對象,並且拖曳到你想放置的區域。許多javascript都類似實作了相關的功能,例如,jQueryUI的draganddrop元件。在HTML5中,拖曳(draganddrop)成為了標準操作,任何元素都支援。正因為這個功能太普遍了,所有的主流瀏覽器都支援這個操作。
啟用拖曳-draggable屬性
非常簡單,只需要將一個元素的拖曳屬性修改為draggable,這個元素就支援拖曳了,如下所示:
拖曳中資料的傳遞
拖曳的過程中,我們往往需要傳遞對應的邏輯資料來完成轉換的過程,這裡主要是使用dataTransfer物件進行資料傳遞,下面先看看它的成員:
方法成員:
setData(format,data):把被拖曳的資料賦值給dataTransfer物件。
format:一個String型參數,指定被拖曳資料的型別。此參數取值可以是「Text」(文字類型)和「URL」(URL類型)。這個參數是大小寫無關的,所以傳入"text"與"Text"是一樣的。
data:一個變體類型參數,指定被拖曳的資料。該數據可以是文本,圖片路徑,URL等等。
此函數有Boolean類型的回傳值,true表示資料成功加到dataTransfer中,false代表不成功。如果需要,可以透過這個參數來決定是否應該繼續執行某些邏輯。
getData(format):取得儲存中存放中存放區的拖曳數據。
format意義與setData中的一樣,取值可以是"Text"(文字類型)和"URL"(URL類型)。
clearData(format):移除指定型別類型的數據。
這裡的format除了上面可以指定的"Text"(文字類型)和"URL"(URL類型)外,還可以取下列值:file-文件,html-html元素,image -圖片。
這個方法可以用來去選擇性的處理拖曳的資料型別。
屬性成員
:
複製碼
effectAllowed:設定或取得資料來源元素中的資料可以執行的操作。
屬性類型為字串,取值範圍如下:
"copy"-複製資料.
"link"-連結資料.
"move"-行動資料
"copyLink"-複製或連結數據,由目標物件決定。
"copyMove"-複製或移動數據,由目標物件決定。
"linkMove"-連結或移動數據,由目標物件決定。
"all"-所有的操作都是支援的。
"none"-禁止拖曳。
"uninitialized"-預設值,採用預設的行為。
注意設定effectAllowed為none以後,拖曳是禁止的,但是滑鼠形狀還是顯示沒有可拖曳的物件的形狀,如果想不顯示這個滑鼠形狀,則需要將window的event事件的屬性returnValue設為false。
程式碼如下:
dropEffect:設定或取得拖曳的目標上允許的操作以及相關的滑鼠形狀。
屬性類型為字串,取值範圍如下:
"copy"-滑鼠顯示為複製時的形狀;
"link"-滑鼠顯示為連接的形狀;
"move"-滑鼠顯示為移動的形狀。
"none"(預設值)-滑鼠顯示為沒有拖曳的形狀。
effectAllowed指定了資料來源支援的操作,所以通常在ondragstart事件中指定。 dropEffect指定了拖曳放置的目標支援的操作,所以與effectAllowed配合,通常在拖曳的目標上的ondragenter,ondragover和ondrop等事件中使用。
files:傳回拖曳的檔案的清單FileList。
types:ondragstart中傳送的資料(被拖曳的資料)類型的清單。
dataTransfer物件的存在,使得在拖曳的資料來源和目標元素之間傳遞邏輯資料變成了可能。通常我們使用setData方法在資料來源元素的ondragstart事件中提供數據,然後再目標元素中,使用getData方法取得資料。
拖曳中觸發的事件 下面是拖曳會發生的事件,基本上事件的觸發順序也就是下面的順序:
dragstart:要被拖曳的元素開始拖曳時觸發,這個事件物件是被觸發拖曳元素。
drag:拖曳元素時觸發,這個事件物件是被拖曳元素。
dragenter:拖曳元素進入目標元素時觸發,這個事件物件就是目標元素。
dragover:拖曳某元素在目標元素上移動時觸發,這個事件物件就是目標元素。
dragleave:拖曳某元素離開目標元素時觸發,這個事件物件就是目標元素。
drop:將被拖曳元素放在目標元素內時觸發,這個事件物件就是目標元素。
dragend:在drop之後觸發,就是拖曳完畢時觸發,這個事件物件是被拖曳元素。
基本上事件的參數event都會傳入相關的元素,可以很方便的進行一些修改。在這裡,我們並不需要處理每個事件,通常只需要掛接主要的幾個事件。
拖曳開始-ondragstart事件 從這個事件傳入的參數含有的信息非常豐富,從中可以很方便的獲取到被拖動的元素(event.Target);從中可以設定被拖曳資料(event.dataTransfer.setData);所以你可以很方便實現拖曳的背後邏輯(當然你綁定的時候也可以傳遞其他的參數)。
拖曳過程中-ondrag,ondragover,ondragenter和ondragleave事件
ondrag事件的物件是被拖曳元素,通常這個事件處理的比較少。 ondragenter事件是當拖曳進入目前元素時發生,ondragleave事件是在拖曳離開目前元素時發生,ondragover事件是在拖曳在目前元素中移動時發生。
這裡只需要注意一點,因為預設情況下,瀏覽器是禁止元素drop的,所以為了讓元素可以drop,需要在這個函數中回傳false或是呼叫event.preventDefault()方法。如下面的例子所示。
拖曳結束-ondrop,ondragend事件 當可拖曳的資料被drop的時候,drop事件觸發。 drop結束後,dragend事件被觸發,這個事件使用的也相對少一點。
看一個簡單的例子:
程式碼如下:
程式碼如下:
程式碼如下:
functionallowDrop(ev){
ev.preventDefault();
}
functiondrag(ev){
ev.dataTransfer.setData("Text",ev.target.id);
}
functiondrop(ev){
vardata=ev.dataTransfer.getData( "Text"); ev.target.appendChild(document.getElementById(data)); ev.preventDefault(); }
檔案拖曳
上面的範例已經使用了dataTransfer的各種方法和屬性,下面再看網路上的另外一個有趣的應用:拖曳一個圖片到網頁上,然後在網頁上顯示。這個應用用到了dataTransfer的files屬性。
已經拖進過來的檔案:
<script> <br />if(window.FileReader){ <br />varlist=document.getElementById('list'), <br />cnt=document.getElementById('container'); <br />//判斷圖片是否<br />functionisImage(type){ <br />switch(type){ <br />case'image/jpeg': <br />case'image/png': <br />case'image/gif': <case'image/png': <br />case'image/gif': <br />case'image/bmp': <br />case'image/jpg': <br />returntrue; <br />default: <br />returnfalse; <br />} <br />} <br />returnfalse; <br />} <br />} <br />//處理拖放檔案清單<br />functionhandleFileSelect(evt){ <br />evt.stopPropagation(); <br />evt.preventDefault(); <br />varfiles=evt.dataTransfer.files; <br />for(vari=0,f; f=files[i];i ){ <br />vart=f.type?f.type:'n/a', <br />reader=newFileReader(), <br />looks=function(f,img){ <br />list.innerHTML ='<li><strong>' f.name '(' t <br />')-' f.size 'bytes<p>' img ' li>'; <br />cnt.innerHTML=img; <br />}, <br />isImg=isImage(t), <br />img; <br />//處理得到的圖片<br />if(isImg){ <br />reader.onload=(function(theFile){ <br />returnfunction(e){ <br />img='<img class="preview"src="' e.target.result '"title="' theFile.名 '"/ alt="突襲HTML5之Javascript API擴充4—拖曳(Drag/Drop)概述_html5教學技巧" >'; <br />looks(theFile,img); <br />}; <br />})(f) <br />reader.readAsDataURL(f); <br />}else{ <br />img ='"o((>ω<))o",你傳進來的不是圖片! ! '; <br />looks(f,img); <br />} <br />} <br />} <br />//處理插入拖曳效果<br />functionhandleDragEnter(evt){this.setAttribute('style', 'border-style:dashed;');} <br />functionhandleDragLeave(evt){this.setAttribute('style','');} <br />//處理檔案拖曳到事件,防止瀏覽器預設事件帶來的重定向<br />functionhandleDragOver(evt){ <br />evt.stopPropagation(); <br />evt.preventDefault(); <br />} <br />cnt.addEventList('sdragenter',handragdragenter'); 🎜>cnt.addEventListener('dragover',handleDragOver,false); <br />cnt.addEventListener('drop',handleFileSelect,false); <br />cnt.addalListener('dragleave',handleDragave,false); }else{ <br />document.getElementById('section').innerHTML='你的瀏覽器不支援啊,同學'; <br />} <br /></script>
這個例子中使用了html5中的檔案讀取API:FileReader物件;這個物件提供了下列非同步方法用於讀取檔案:
1.FileReader.readAsBinaryString (fileBlob)
以二進位的方式讀取文件,result屬性會包含一個文件的二進位的格式
2.FileReader.readAsText(fileBlob,opt_encoding)
以文字的方式讀取文件,result屬性將會包含一個檔案的文字格式,預設解碼參數是“utf-8”。
3.FileReader.readAsDataURL(file)
以URL形式讀取檔案result將會包含一個檔案的DataURL格式(圖片通常用這種方式)。
使用上面的方法讀取檔案後,會觸發下列事件:
程式碼如下:
onloadstart,onprogress,onabort,onerror,onload,onloadend
這些事件都很簡單,需要的時候掛接就可以了。看下面的程式碼範例:
程式碼如下:
程式碼如下:
func {
//obtaininputelementthroughDOM
varfile=document.getElementById('file').files[0];
if(file){
getAsText(file);
}
}
}
functiongetAsText(readFile){
varreader=newFileReader();
//ReadfileintomemoryasUTF-16
reader.readAsText(readFile,"UTF-16");
reader.readAsText(readFile,"UTF-16");
> anderrors
reader.onprogress=updateProgress;
reader.onload=loaded;
reader.onerror=errorHandler;
}
functionupdateProgress(evt){ //evt.loadedandevt.totalareProgressEventproperties
varloaded=(evt.loaded/evt.total);
if(loaded//Increasetheprogbarlength /style. (loaded*200) "px";
}
}
}
functionloaded(evt){
//Obtainthereadfiledata
varfileString=evt.target.result;
/ /HandleUTF-16filedump
if(utils.regexp.isChinese(fileString)){
//ChineseCharacters Namevalidation
}
else{
//runothercharsettest
} xhr.send(fileString)
}
functionerrorHandler(evt){
if(evt.target.error.name=="NotReadableErr"){
//Thefilecouldnotberead
複製程式碼
程式碼如下:
window.open('http://aaa.bbbb.com/ccc.rar','_blank')
實用參考:
官方文件:http://www.w3schools.com/html5/
一個不錯的教學網址:http://html5.phphubei.com/html5/features/DrapAndDrop/MSDN幫助:http://msdn.microsoft.com/en-us/library/ms535861(v=vs.85 ).aspx
文件拖曳詳述:http://www.html5rocks.com/zh/tutorials/file/dndfiles/
檔案拖曳並上傳:http://www.chinaz.com/design/2010/0909/131984.shtml
檔案拖曳上傳完整範例:http://www.cnblogs.com/liaofeng/archive/ 2011/05/18/2049928.html
檔案下載的範例:http://hi.baidu.com/guo_biru/item/2d7201c012b6debd0c0a7b05http://www.cnblogs.com/liulf/archive/2010/03/01/1675511.htmlwindow.open參數:http://www.koyoz.com/blog /?action=show&id=176