DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> HTML基礎知識 >> HTML5詳解 >> 突襲HTML5之Javascript API擴展4―拖拽(Drag/Drop)概述
突襲HTML5之Javascript API擴展4―拖拽(Drag/Drop)概述
編輯:HTML5詳解     
拖拽(Drag/Drop)是個非常普遍的功能。你可以抓住一個對象,並且拖動到你想放置的區域。很多Javascript都類似實現了相關的功能,例如,jQueryUI的draganddrop組件。在Html5中,拖拽(draganddrop)成為了標准操作,任何元素都支持。正因為這個功能太普遍了,所有的主流浏覽器都支持這個操作。 
啟用拖拽-draggable屬性 
非常簡單,只需要將一個元素的拖動屬性修改為draggable,這個元素就支持拖動了,如下所示: 

復制代碼代碼如下:
<imgdraggable="true"/> 

拖動中數據的傳遞 
拖動的過程中,我們往往需要傳遞相應的邏輯數據來完成轉換的過程,這裡主要是使用dataTransfer對象進行數據傳遞,下面先看看它的成員: 
方法成員: 

復制代碼代碼如下:
setData(format,data):把被拖動的數據賦值給dataTransfer對象。 

format:一個String型參數,指定被拖動數據的類型。該參數取值可以是“Text”(文本類型)和“URL”(URL類型)。該參數是大小寫無關的,所以傳入"text"與"Text"是一樣的。 
data:一個變體類型參數,指定被拖動的數據。該數據可以是文本,圖片路徑,URL等等。 
該函數有Boolean類型的返回值,true表示數據成功加到dataTransfer中,false代表不成功。如果需要,可以通過這個參數來決定是否應該繼續執行某些邏輯。 

復制代碼代碼如下:
getData(format):獲取dataTransfer中存放的拖動數據。 

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事件被觸發,這個事件使用的也相對少一點。 
看一個簡單的例子: 

復制代碼代碼如下:
<!DOCTYPEHtml> 
<Html> 
<head> 
<scripttype="text/Javascript"> 
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(); 

</script> 
</head> 
<body> 
<divid="div1"ondrop="drop(event)"ondragover="allowDrop(event)"></div> 
<imgid="drag1"src="img_logo.gif"draggable="true"ondragstart="drag(event)"width="336"height="69"/> 
</body> 
</Html> 

文件拖拽 
上面的例子已經使用了dataTransfer的各種方法和屬性,下面再看網上的另外一個有趣的應用:拖拽一個圖片到網頁上,然後在網頁上顯示。這個應用用到了dataTransfer的files屬性。 

復制代碼代碼如下:
<!DOCTYPEHtml> 
<Html> 
<head> 
<metacharset="utf-8"> 
<title>Html5拖放文件</title> 
<style> 
#section{font-family:"Georgia","微軟雅黑","華文中宋";} 
.container{display:inline-block;min-height:200px;min-width:360px;color:#f30;padding:30px;border:3pxsolid#ddd;-moz-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;} 
.prevIEw{max-width:360px;} 
#files-list{position:absolute;top:0;left:500px;} 
#list{width:460px;} 
#list.prevIEw{max-width:250px;} 
#listp{color:#888;font-size:12px;} 
#list.green{color:#09c;} 
</style> 
</head> 
<body> 
<divid="section"> 
<p>把你的圖片拖到下面的容器內:</p> 
<divid="container"class="container"> 
</div> 
<divid="files-list"> 
<p>已經拖進過來的文件:</p> 
<ulid="list"></ul> 
</div> 
</div> 
<script> 
if(window.FileReader){ 
varlist=document.getElementById('list'), 
cnt=document.getElementById('container'); 
//判斷是否圖片 
functionisImage(type){ 
switch(type){ 
case'image/jpeg': 
case'image/png': 
case'image/gif': 
case'image/bmp': 
case'image/jpg': 
returntrue; 
default: 
returnfalse; 


//處理拖放文件列表 
functionhandleFileSelect(evt){ 
evt.stopPropagation(); 
evt.preventDefault(); 
varfiles=evt.dataTransfer.files; 
for(vari=0,f;f=files[i];i++){ 
vart=f.type?f.type:'n/a', 
reader=newFileReader(), 
looks=function(f,img){ 
list.innerHtml+='<li><strong>'+f.name+'</strong>('+t+ 
')-'+f.size+'bytes<p>'+img+'</p></li>'; 
cnt.innerHtml=img; 
}, 
isImg=isImage(t), 
img; 
//處理得到的圖片 
if(isImg){ 
reader.onload=(function(theFile){ 
returnfunction(e){ 
img='<imgclass="prevIEw"src="'+e.target.result+'"title="'+theFile.name+'"/>'; 
looks(theFile,img); 
}; 
})(f) 
reader.readAsDataURL(f); 
}else{ 
img='"o((>ω<))o",你傳進來的不是圖片!!'; 
looks(f,img); 



//處理插入拖出效果 
functionhandleDragEnter(evt){this.setAttribute('style','border-style:dashed;');} 
functionhandleDragLeave(evt){this.setAttribute('style','');} 
//處理文件拖入事件,防止浏覽器默認事件帶來的重定向 
functionhandleDragOver(evt){ 
evt.stopPropagation(); 
evt.preventDefault(); 

cnt.addEventListener('dragenter',handleDragEnter,false); 
cnt.addEventListener('dragover',handleDragOver,false); 
cnt.addEventListener('drop',handleFileSelect,false); 
cnt.addEventListener('dragleave',handleDragLeave,false); 
}else{ 
document.getElementById('section').innerHtml='你的浏覽器不支持啊,同學'; 

</script> 
</body> 
</Html> 

這個例子中使用了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 

這些事件都很簡單,需要的時候掛接就可以了。看下面的代碼示例: 

復制代碼代碼如下:
functionstartRead(){ 
//obtaininputelementthroughDOM 
varfile=document.getElementById('file').files[0]; 
if(file){ 
getAsText(file); 


functiongetAsText(readFile){ 
varreader=newFileReader(); 
//ReadfileintomemoryasUTF-16 
reader.readAsText(readFile,"UTF-16"); 
//Handleprogress,success,anderrors 
reader.onprogress=updateProgress; 
reader.onload=loaded; 
reader.onerror=errorHandler; 

functionupdateProgress(evt){ 
if(evt.lengthComputable){ 
//evt.loadedandevt.totalareProgressEventpropertIEs 
varloaded=(evt.loaded/evt.total); 
if(loaded<1){ 
//Increasetheprogbarlength 
//style.width=(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方法,例如: 

復制代碼代碼如下:
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/2d7201c012b6debd0c0a7b05
window.open攻略:http://www.cnblogs.com/liulf/archive/2010/03/01/1675511.Html
window.open參數:http://www.koyoz.com/blog/?action=show&id=176 
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved