更新時間:2023-03-23 來源:黑馬程序員 瀏覽量:
拖曳是頁面中的元素從初始位置被拖動到新的位置的用戶行為,如拖曳頁面中的指定元素到另一個元素中。首先使用鼠標(biāo)指針進入源對象,然后按住鼠標(biāo)左鍵拖動源對象,當(dāng)移動鼠標(biāo)時源對象會跟隨鼠標(biāo)指針移動,如果源對象進入了目標(biāo)對象,就松開鼠標(biāo)左鍵讓源對象放置在目標(biāo)對象中。
在拖曳操作中,源對象表示被拖動的元素。為元素添加draggable屬性可以設(shè)置此元素為源對象,示例代碼如下:
<p draggable?"true"></p>
上述代碼設(shè)置<p>標(biāo)簽的draggable屬性的值為true,表示<p>標(biāo)簽是一個可以被鼠標(biāo)拖曳的源對象。需要注意的是,圖片和鏈接默認(rèn)是可以拖動的,它們不用添加draggable屬性,就可以進行拖曳。
源對象進入的元素稱為目標(biāo)對象,目標(biāo)對象可以是頁面中的任一元素,示例代碼如下:
<div></div>
<div>標(biāo)簽不需要設(shè)置draggable屬性。
拖曳事件包括拖曳開始、拖曳進行中、拖曳結(jié)束等事件。在開發(fā)中,用戶可以依靠拖曳事件來實現(xiàn)帶有拖曳交互效果的頁面。拖曳事件是由元素對象產(chǎn)生的,如源對象、目標(biāo)對象,這些對象會產(chǎn)生不同的拖曳事件。源對象事件如表所示。
目標(biāo)對象事件表如下:
需要注意的是,只有當(dāng)源對象上的鼠標(biāo)指針進入目標(biāo)對象時,才會觸發(fā)ondragenter事件。默認(rèn)情況下,瀏覽器會默認(rèn)阻止ondrop事件。如果想要觸發(fā)該事件,則需要在ondragover事件中使用“retum false;”(或者e.preventDefaultO)來阻止其默認(rèn)行為。
在源對象和目標(biāo)對象的事件處理函數(shù)中,使用dataTransfer對象可以進行數(shù)據(jù)傳輸,示例代碼如下:
// 通過 dataTransfer對象設(shè)置數(shù)據(jù) event.dataTransfer.setData(format, data); // 通過dataTransfer對象獲取數(shù)據(jù) event.dataTransfer.getData(format);
上述代碼中,event表示事件處理函數(shù)的事件源對象,setData(format,data)方法用于將指定格式的數(shù)據(jù)設(shè)置給dataTransfer對象,參數(shù)format用于定義數(shù)據(jù)的格式,data表示待設(shè)置的數(shù)據(jù):getData(format)方法可以從dataTransfer對象中獲取指定格式的數(shù)據(jù),format 表示數(shù)據(jù)的格式。
下面演示HTML5中拖曳事件的具體使用方法。
(1)創(chuàng)建C:codelchapter02demo09.html,定義源對象p和目標(biāo)對象div頁面結(jié)構(gòu),具體代碼如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Document</title> <style> * { margin: 0; padding: 0; } div { width:200px; height:200px; border: lpx solid red; float: left; malin: 10px; } div:nth-child(2) { border: lpx solid green; } div:nth-child(3) { border: lpx solid blue; } p{ height: 25px; background-color: pink; 1ine-height: 25px; text-align: center; } </style> </head> <body> <div id="divl"> <p id="p1"draggable="true">施曳內(nèi)容1</p> <p id="p2"draggable="true">施曳內(nèi)容2</p> <p id="p3"draggable="true">拖曳內(nèi)容3</p> <p id="p4"draggable="true">拖曳內(nèi)客4</p> </div> <div id="div2"></div> <div id="div3"></div> </body> </html>
上述代碼中,第33~40行代碼定義了3個div盒子作為目標(biāo)對象,元素id值分別是divl、div2和div3。在div1盒子中,放置了4個p元素作為源對象,這些元素的id值分別為p1、p2、p3和p4。
(2)保存代碼,在瀏覽器中進行測試,效果如圖。
(3)在第(1)步第40行代碼后,編寫如下代碼,設(shè)置源對象的拖曳效果:
<script> // 當(dāng)拖曳開始時觸發(fā) document.ondragstart=function (event){ console.log('源對象開始被拖動'); console.log (event.target.id); event.dataTransfer.setData('text/html',event.target.id);//傳遞id值}; //作用于整個拖曳過程(不斷地執(zhí)行) document.ondrag=function(event){ console.log('源對象被拖動過程中'); }; //當(dāng)拖曳結(jié)束時觸發(fā) document.ondragend=function (event){ console.log('源對象被拖動結(jié)束'); }; </script>
上述代碼中,event.target用來獲取觸發(fā)事件的子盒子。由于源對象是可以在目標(biāo)對象中任意來回拖動的,所以使用document作為父盒子,在這里將事件對象委托給document元素。第3-7行代碼用于實現(xiàn)源對象被拖動時的數(shù)據(jù)存儲。其中,第6行代碼在拖曳操作時使用dataTransfer對象存儲數(shù)據(jù),該對象可以保存一項或多項數(shù)據(jù),支持多種數(shù)據(jù)型(如URL、text/html類型)。dataTransfer對象的setDataO方法可以為一個給定的類型設(shè)置數(shù)據(jù),傳遞 event.target.id 用于記錄當(dāng)前被拖曳的源對象的id。
(4)在瀏覽器中刷新瀏覽器頁面,并打開控制臺,查看源對象的事件過程,頁面效果如圖。
當(dāng)拖動id為p4的元素“拖曳內(nèi)容4”時,控制臺中會打印出該元素的id值,以及源對象開始被拖動、被拖動過程中和被拖動結(jié)束時的一系列監(jiān)聽。讀者可以根據(jù)控制臺打印的數(shù)據(jù)來觀察監(jiān)聽過程。
(5)繼續(xù)編寫如下代碼,設(shè)置目標(biāo)對象的釋放效果:
//當(dāng)源對象進入目標(biāo)對象時 document.ondragenter=function (event){ console.log('目標(biāo)對象被源對象拖動著進入'); console.log (event.target); }; //當(dāng)源對象懸停在目標(biāo)對象上方時觸發(fā) document.ondragover=function (event) { console.1og('源對象懸停在目標(biāo)對象上方'): return false; }; // 當(dāng)源對象離開目標(biāo)對象時 docuwlnt.ondragleave=function() { console.log('離開了'); }; //當(dāng)源對象在目標(biāo)對象上方釋放鼠標(biāo)時 document.ondrop=function (event){ console.1og('上方釋放/松手'); var id = event.dataTransfer.getData('text/html'); event.target.appendChild(document.getElementById(id)); };
上述代碼定義了應(yīng)用于目標(biāo)對象的一系列監(jiān)聽事件。第16~20行代碼實現(xiàn)了當(dāng)源對象在目標(biāo)對象上釋放(松開)鼠標(biāo)時,將源對象放入目標(biāo)對象的效果。其中,第18行代碼使用dataTransfer對象的getData()方法,獲取之前使用 setDataO方法存入的id值;第19行代碼使用document.getElementByld)獲取id值對應(yīng)的元素,并使用appendChild()方法將其追加到event.target 目標(biāo)對象中。
(6)在瀏覽器中刷新,然后進行拖曳操作,查看源對象進入目標(biāo)對象的事件過程,頁面效果如圖。