首頁(yè)技術(shù)文章正文

HTML5中如何實(shí)現(xiàn)拖曳交互效果?

更新時(shí)間:2023-03-23 來(lái)源:黑馬程序員 瀏覽量:

拖曳是頁(yè)面中的元素從初始位置被拖動(dòng)到新的位置的用戶行為,如拖曳頁(yè)面中的指定元素到另一個(gè)元素中。首先使用鼠標(biāo)指針進(jìn)入源對(duì)象,然后按住鼠標(biāo)左鍵拖動(dòng)源對(duì)象,當(dāng)移動(dòng)鼠標(biāo)時(shí)源對(duì)象會(huì)跟隨鼠標(biāo)指針移動(dòng),如果源對(duì)象進(jìn)入了目標(biāo)對(duì)象,就松開鼠標(biāo)左鍵讓源對(duì)象放置在目標(biāo)對(duì)象中。

在拖曳操作中,源對(duì)象表示被拖動(dòng)的元素。為元素添加draggable屬性可以設(shè)置此元素為源對(duì)象,示例代碼如下:

<p draggable?"true"></p>

上述代碼設(shè)置<p>標(biāo)簽的draggable屬性的值為true,表示<p>標(biāo)簽是一個(gè)可以被鼠標(biāo)拖曳的源對(duì)象。需要注意的是,圖片和鏈接默認(rèn)是可以拖動(dòng)的,它們不用添加draggable屬性,就可以進(jìn)行拖曳。

源對(duì)象進(jìn)入的元素稱為目標(biāo)對(duì)象,目標(biāo)對(duì)象可以是頁(yè)面中的任一元素,示例代碼如下:

<div></div>

<div>標(biāo)簽不需要設(shè)置draggable屬性。 

拖曳事件包括拖曳開始、拖曳進(jìn)行中、拖曳結(jié)束等事件。在開發(fā)中,用戶可以依靠拖曳事件來(lái)實(shí)現(xiàn)帶有拖曳交互效果的頁(yè)面。拖曳事件是由元素對(duì)象產(chǎn)生的,如源對(duì)象、目標(biāo)對(duì)象,這些對(duì)象會(huì)產(chǎn)生不同的拖曳事件。源對(duì)象事件如表所示。
1679560472204_83.png
目標(biāo)對(duì)象事件表如下:
1679560651155_77.png

需要注意的是,只有當(dāng)源對(duì)象上的鼠標(biāo)指針進(jìn)入目標(biāo)對(duì)象時(shí),才會(huì)觸發(fā)ondragenter事件。默認(rèn)情況下,瀏覽器會(huì)默認(rèn)阻止ondrop事件。如果想要觸發(fā)該事件,則需要在ondragover事件中使用“retum false;”(或者e.preventDefaultO)來(lái)阻止其默認(rèn)行為。

在源對(duì)象和目標(biāo)對(duì)象的事件處理函數(shù)中,使用dataTransfer對(duì)象可以進(jìn)行數(shù)據(jù)傳輸,示例代碼如下:

// 通過(guò) dataTransfer對(duì)象設(shè)置數(shù)據(jù)
event.dataTransfer.setData(format, data);
// 通過(guò)dataTransfer對(duì)象獲取數(shù)據(jù)
event.dataTransfer.getData(format);

上述代碼中,event表示事件處理函數(shù)的事件源對(duì)象,setData(format,data)方法用于將指定格式的數(shù)據(jù)設(shè)置給dataTransfer對(duì)象,參數(shù)format用于定義數(shù)據(jù)的格式,data表示待設(shè)置的數(shù)據(jù):getData(format)方法可以從dataTransfer對(duì)象中獲取指定格式的數(shù)據(jù),format 表示數(shù)據(jù)的格式。

下面演示HTML5中拖曳事件的具體使用方法。

(1)創(chuàng)建C:codelchapter02demo09.html,定義源對(duì)象p和目標(biāo)對(duì)象div頁(yè)面結(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個(gè)div盒子作為目標(biāo)對(duì)象,元素id值分別是divl、div2和div3。在div1盒子中,放置了4個(gè)p元素作為源對(duì)象,這些元素的id值分別為p1、p2、p3和p4。

(2)保存代碼,在瀏覽器中進(jìn)行測(cè)試,效果如圖。

1679561619261_84.png

(3)在第(1)步第40行代碼后,編寫如下代碼,設(shè)置源對(duì)象的拖曳效果:

<script>
  // 當(dāng)拖曳開始時(shí)觸發(fā)
  document.ondragstart=function (event){
    console.log('源對(duì)象開始被拖動(dòng)');
    console.log (event.target.id);
    event.dataTransfer.setData('text/html',event.target.id);//傳遞id值};
  //作用于整個(gè)拖曳過(guò)程(不斷地執(zhí)行)
  document.ondrag=function(event){
    console.log('源對(duì)象被拖動(dòng)過(guò)程中');
  };
  //當(dāng)拖曳結(jié)束時(shí)觸發(fā)
  document.ondragend=function (event){
    console.log('源對(duì)象被拖動(dòng)結(jié)束');
  };
</script>

上述代碼中,event.target用來(lái)獲取觸發(fā)事件的子盒子。由于源對(duì)象是可以在目標(biāo)對(duì)象中任意來(lái)回拖動(dòng)的,所以使用document作為父盒子,在這里將事件對(duì)象委托給document元素。第3-7行代碼用于實(shí)現(xiàn)源對(duì)象被拖動(dòng)時(shí)的數(shù)據(jù)存儲(chǔ)。其中,第6行代碼在拖曳操作時(shí)使用dataTransfer對(duì)象存儲(chǔ)數(shù)據(jù),該對(duì)象可以保存一項(xiàng)或多項(xiàng)數(shù)據(jù),支持多種數(shù)據(jù)型(如URL、text/html類型)。dataTransfer對(duì)象的setDataO方法可以為一個(gè)給定的類型設(shè)置數(shù)據(jù),傳遞 event.target.id 用于記錄當(dāng)前被拖曳的源對(duì)象的id。

(4)在瀏覽器中刷新瀏覽器頁(yè)面,并打開控制臺(tái),查看源對(duì)象的事件過(guò)程,頁(yè)面效果如圖。

1679562169129_78.png

當(dāng)拖動(dòng)id為p4的元素“拖曳內(nèi)容4”時(shí),控制臺(tái)中會(huì)打印出該元素的id值,以及源對(duì)象開始被拖動(dòng)、被拖動(dòng)過(guò)程中和被拖動(dòng)結(jié)束時(shí)的一系列監(jiān)聽。讀者可以根據(jù)控制臺(tái)打印的數(shù)據(jù)來(lái)觀察監(jiān)聽過(guò)程。

(5)繼續(xù)編寫如下代碼,設(shè)置目標(biāo)對(duì)象的釋放效果:

//當(dāng)源對(duì)象進(jìn)入目標(biāo)對(duì)象時(shí)
document.ondragenter=function (event){
  console.log('目標(biāo)對(duì)象被源對(duì)象拖動(dòng)著進(jìn)入');
  console.log (event.target);
};
//當(dāng)源對(duì)象懸停在目標(biāo)對(duì)象上方時(shí)觸發(fā)
document.ondragover=function (event) {
  console.1og('源對(duì)象懸停在目標(biāo)對(duì)象上方'):
  return false;
};
// 當(dāng)源對(duì)象離開目標(biāo)對(duì)象時(shí)
docuwlnt.ondragleave=function() {
console.log('離開了');
};
//當(dāng)源對(duì)象在目標(biāo)對(duì)象上方釋放鼠標(biāo)時(shí)
document.ondrop=function (event){
  console.1og('上方釋放/松手');
  var id = event.dataTransfer.getData('text/html');
  event.target.appendChild(document.getElementById(id));
};

上述代碼定義了應(yīng)用于目標(biāo)對(duì)象的一系列監(jiān)聽事件。第16~20行代碼實(shí)現(xiàn)了當(dāng)源對(duì)象在目標(biāo)對(duì)象上釋放(松開)鼠標(biāo)時(shí),將源對(duì)象放入目標(biāo)對(duì)象的效果。其中,第18行代碼使用dataTransfer對(duì)象的getData()方法,獲取之前使用 setDataO方法存入的id值;第19行代碼使用document.getElementByld)獲取id值對(duì)應(yīng)的元素,并使用appendChild()方法將其追加到event.target 目標(biāo)對(duì)象中。

(6)在瀏覽器中刷新,然后進(jìn)行拖曳操作,查看源對(duì)象進(jìn)入目標(biāo)對(duì)象的事件過(guò)程,頁(yè)面效果如圖。

拖曳

分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!