JavaScript 拖拉事件

2023-03-20 15:46 更新

拖拉事件的種類 

拖拉(drag)指的是,用戶在某個(gè)對(duì)象上按下鼠標(biāo)鍵不放,拖動(dòng)它到另一個(gè)位置,然后釋放鼠標(biāo)鍵,將該對(duì)象放在那里。

拖拉的對(duì)象有好幾種,包括元素節(jié)點(diǎn)、圖片、鏈接、選中的文字等等。在網(wǎng)頁(yè)中,除了元素節(jié)點(diǎn)默認(rèn)不可以拖拉,其他(圖片、鏈接、選中的文字)都可以直接拖拉。為了讓元素節(jié)點(diǎn)可拖拉,可以將該節(jié)點(diǎn)的draggable屬性設(shè)為true

<div draggable="true">
  此區(qū)域可拖拉
</div>

上面代碼的div區(qū)塊,在網(wǎng)頁(yè)中可以直接用鼠標(biāo)拖動(dòng)。松開鼠標(biāo)鍵時(shí),拖動(dòng)效果就會(huì)消失,該區(qū)塊依然在原來的位置。

draggable屬性可用于任何元素節(jié)點(diǎn),但是圖片(<img>)和鏈接(<a>)不加這個(gè)屬性,就可以拖拉。對(duì)于它們,用到這個(gè)屬性的時(shí)候,往往是將其設(shè)為false,防止拖拉這兩種元素。

注意,一旦某個(gè)元素節(jié)點(diǎn)的draggable屬性設(shè)為true,就無法再用鼠標(biāo)選中該節(jié)點(diǎn)內(nèi)部的文字或子節(jié)點(diǎn)了。

當(dāng)元素節(jié)點(diǎn)或選中的文本被拖拉時(shí),就會(huì)持續(xù)觸發(fā)拖拉事件,包括以下一些事件。

  • drag:拖拉過程中,在被拖拉的節(jié)點(diǎn)上持續(xù)觸發(fā)(相隔幾百毫秒)。
  • dragstart:用戶開始拖拉時(shí),在被拖拉的節(jié)點(diǎn)上觸發(fā),該事件的target屬性是被拖拉的節(jié)點(diǎn)。通常應(yīng)該在這個(gè)事件的監(jiān)聽函數(shù)中,指定拖拉的數(shù)據(jù)。
  • dragend:拖拉結(jié)束時(shí)(釋放鼠標(biāo)鍵或按下 ESC 鍵)在被拖拉的節(jié)點(diǎn)上觸發(fā),該事件的target屬性是被拖拉的節(jié)點(diǎn)。它與dragstart事件,在同一個(gè)節(jié)點(diǎn)上觸發(fā)。不管拖拉是否跨窗口,或者中途被取消,dragend事件總是會(huì)觸發(fā)的。
  • dragenter:拖拉進(jìn)入當(dāng)前節(jié)點(diǎn)時(shí),在當(dāng)前節(jié)點(diǎn)上觸發(fā)一次,該事件的target屬性是當(dāng)前節(jié)點(diǎn)。通常應(yīng)該在這個(gè)事件的監(jiān)聽函數(shù)中,指定是否允許在當(dāng)前節(jié)點(diǎn)放下(drop)拖拉的數(shù)據(jù)。如果當(dāng)前節(jié)點(diǎn)沒有該事件的監(jiān)聽函數(shù),或者監(jiān)聽函數(shù)不執(zhí)行任何操作,就意味著不允許在當(dāng)前節(jié)點(diǎn)放下數(shù)據(jù)。在視覺上顯示拖拉進(jìn)入當(dāng)前節(jié)點(diǎn),也是在這個(gè)事件的監(jiān)聽函數(shù)中設(shè)置。
  • dragover:拖拉到當(dāng)前節(jié)點(diǎn)上方時(shí),在當(dāng)前節(jié)點(diǎn)上持續(xù)觸發(fā)(相隔幾百毫秒),該事件的target屬性是當(dāng)前節(jié)點(diǎn)。該事件與dragenter事件的區(qū)別是,dragenter事件在進(jìn)入該節(jié)點(diǎn)時(shí)觸發(fā),然后只要沒有離開這個(gè)節(jié)點(diǎn),dragover事件會(huì)持續(xù)觸發(fā)。
  • dragleave:拖拉操作離開當(dāng)前節(jié)點(diǎn)范圍時(shí),在當(dāng)前節(jié)點(diǎn)上觸發(fā),該事件的target屬性是當(dāng)前節(jié)點(diǎn)。如果要在視覺上顯示拖拉離開操作當(dāng)前節(jié)點(diǎn),就在這個(gè)事件的監(jiān)聽函數(shù)中設(shè)置。
  • drop:被拖拉的節(jié)點(diǎn)或選中的文本,釋放到目標(biāo)節(jié)點(diǎn)時(shí),在目標(biāo)節(jié)點(diǎn)上觸發(fā)。注意,如果當(dāng)前節(jié)點(diǎn)不允許drop,即使在該節(jié)點(diǎn)上方松開鼠標(biāo)鍵,也不會(huì)觸發(fā)該事件。如果用戶按下 ESC 鍵,取消這個(gè)操作,也不會(huì)觸發(fā)該事件。該事件的監(jiān)聽函數(shù)負(fù)責(zé)取出拖拉數(shù)據(jù),并進(jìn)行相關(guān)處理。

下面的例子展示,如何動(dòng)態(tài)改變被拖動(dòng)節(jié)點(diǎn)的背景色。

div.addEventListener('dragstart', function (e) {
  this.style.backgroundColor = 'red';
}, false);

div.addEventListener('dragend', function (e) {
  this.style.backgroundColor = 'green';
}, false);

上面代碼中,div節(jié)點(diǎn)被拖動(dòng)時(shí),背景色會(huì)變?yōu)榧t色,拖動(dòng)結(jié)束,又變回綠色。

下面是一個(gè)例子,展示如何實(shí)現(xiàn)將一個(gè)節(jié)點(diǎn)從當(dāng)前父節(jié)點(diǎn),拖拉到另一個(gè)父節(jié)點(diǎn)中。

/* HTML 代碼如下
 <div class="dropzone">
   <div id="draggable" draggable="true">
     該節(jié)點(diǎn)可拖拉
   </div>
 </div>
 <div class="dropzone"></div>
 <div class="dropzone"></div>
 <div class="dropzone"></div>
*/

// 被拖拉節(jié)點(diǎn)
var dragged;

document.addEventListener('dragstart', function (event) {
  // 保存被拖拉節(jié)點(diǎn)
  dragged = event.target;
  // 被拖拉節(jié)點(diǎn)的背景色變透明
  event.target.style.opacity = 0.5;
}, false);

document.addEventListener('dragend', function (event) {
  // 被拖拉節(jié)點(diǎn)的背景色恢復(fù)正常
  event.target.style.opacity = '';
}, false);

document.addEventListener('dragover', function (event) {
  // 防止拖拉效果被重置,允許被拖拉的節(jié)點(diǎn)放入目標(biāo)節(jié)點(diǎn)
  event.preventDefault();
}, false);

document.addEventListener('dragenter', function (event) {
  // 目標(biāo)節(jié)點(diǎn)的背景色變紫色
  // 由于該事件會(huì)冒泡,所以要過濾節(jié)點(diǎn)
  if (event.target.className === 'dropzone') {
    event.target.style.background = 'purple';
  }
}, false);

document.addEventListener('dragleave', function( event ) {
  // 目標(biāo)節(jié)點(diǎn)的背景色恢復(fù)原樣
  if (event.target.className === 'dropzone') {
    event.target.style.background = '';
  }
}, false);

document.addEventListener('drop', function( event ) {
  // 防止事件默認(rèn)行為(比如某些元素節(jié)點(diǎn)上可以打開鏈接),
  event.preventDefault();
  if (event.target.className === 'dropzone') {
    // 恢復(fù)目標(biāo)節(jié)點(diǎn)背景色
    event.target.style.background = '';
    // 將被拖拉節(jié)點(diǎn)插入目標(biāo)節(jié)點(diǎn)
    dragged.parentNode.removeChild(dragged);
    event.target.appendChild( dragged );
  }
}, false);

關(guān)于拖拉事件,有以下幾個(gè)注意點(diǎn)。

  • 拖拉過程只觸發(fā)以上這些拖拉事件,盡管鼠標(biāo)在移動(dòng),但是鼠標(biāo)事件不會(huì)觸發(fā)。
  • 將文件從操作系統(tǒng)拖拉進(jìn)瀏覽器,不會(huì)觸發(fā)dragstartdragend事件。
  • dragenterdragover事件的監(jiān)聽函數(shù),用來取出拖拉的數(shù)據(jù)(即允許放下被拖拉的元素)。由于網(wǎng)頁(yè)的大部分區(qū)域不適合作為放下拖拉元素的目標(biāo)節(jié)點(diǎn),所以這兩個(gè)事件的默認(rèn)設(shè)置為當(dāng)前節(jié)點(diǎn)不允許接受被拖拉的元素。如果想要在目標(biāo)節(jié)點(diǎn)上放下的數(shù)據(jù),首先必須阻止這兩個(gè)事件的默認(rèn)行為。
<div ondragover="return false">
<div ondragover="event.preventDefault()">

上面代碼中,如果不取消拖拉事件或者阻止默認(rèn)行為,就不能在div節(jié)點(diǎn)上放下被拖拉的節(jié)點(diǎn)。

DragEvent 接口 

拖拉事件都繼承了DragEvent接口,這個(gè)接口又繼承了MouseEvent接口和Event接口。

瀏覽器原生提供一個(gè)DragEvent()構(gòu)造函數(shù),用來生成拖拉事件的實(shí)例對(duì)象。

new DragEvent(type, options)

DragEvent()構(gòu)造函數(shù)接受兩個(gè)參數(shù),第一個(gè)參數(shù)是字符串,表示事件的類型,該參數(shù)必須;第二個(gè)參數(shù)是事件的配置對(duì)象,用來設(shè)置事件的屬性,該參數(shù)可選。配置對(duì)象除了接受MouseEvent接口和Event接口的配置屬性,還可以設(shè)置dataTransfer屬性要么是null,要么是一個(gè)DataTransfer接口的實(shí)例。

DataTransfer的實(shí)例對(duì)象用來讀寫拖拉事件中傳輸?shù)臄?shù)據(jù),詳見下文《DataTransfer 接口》的部分。

DataTransfer 接口概述 

所有拖拉事件的實(shí)例都有一個(gè)DragEvent.dataTransfer屬性,用來讀寫需要傳遞的數(shù)據(jù)。這個(gè)屬性的值是一個(gè)DataTransfer接口的實(shí)例。

瀏覽器原生提供一個(gè)DataTransfer()構(gòu)造函數(shù),用來生成DataTransfer實(shí)例對(duì)象。

var dataTrans = new DataTransfer();

DataTransfer()構(gòu)造函數(shù)不接受參數(shù)。

拖拉的數(shù)據(jù)分成兩方面:數(shù)據(jù)的種類(又稱格式)和數(shù)據(jù)的值。數(shù)據(jù)的種類是一個(gè) MIME 字符串(比如text/plainimage/jpeg),數(shù)據(jù)的值是一個(gè)字符串。一般來說,如果拖拉一段文本,則數(shù)據(jù)默認(rèn)就是那段文本;如果拖拉一個(gè)鏈接,則數(shù)據(jù)默認(rèn)就是鏈接的 URL。

拖拉事件開始時(shí),開發(fā)者可以提供數(shù)據(jù)類型和數(shù)據(jù)值。拖拉過程中,開發(fā)者通過dragenterdragover事件的監(jiān)聽函數(shù),檢查數(shù)據(jù)類型,以確定是否允許放下(drop)被拖拉的對(duì)象。比如,在只允許放下鏈接的區(qū)域,檢查拖拉的數(shù)據(jù)類型是否為text/uri-list。

發(fā)生drop事件時(shí),監(jiān)聽函數(shù)取出拖拉的數(shù)據(jù),對(duì)其進(jìn)行處理。

DataTransfer 的實(shí)例屬性 

DataTransfer.dropEffect 

DataTransfer.dropEffect屬性用來設(shè)置放下(drop)被拖拉節(jié)點(diǎn)時(shí)的效果,會(huì)影響到拖拉經(jīng)過相關(guān)區(qū)域時(shí)鼠標(biāo)的形狀。它可能取下面的值。

  • copy:復(fù)制被拖拉的節(jié)點(diǎn)
  • move:移動(dòng)被拖拉的節(jié)點(diǎn)
  • link:創(chuàng)建指向被拖拉的節(jié)點(diǎn)的鏈接
  • none:無法放下被拖拉的節(jié)點(diǎn)

除了上面這些值,設(shè)置其他的值都是無效的。

target.addEventListener('dragover', function (e) {
  e.preventDefault();
  e.stopPropagation();
  e.dataTransfer.dropEffect = 'copy';
});

上面代碼中,被拖拉元素一旦drop,接受的區(qū)域會(huì)復(fù)制該節(jié)點(diǎn)。

dropEffect屬性一般在dragenterdragover事件的監(jiān)聽函數(shù)中設(shè)置,對(duì)于dragstart、drag、dragleave這三個(gè)事件,該屬性不起作用。因?yàn)樵搶傩灾粚?duì)接受被拖拉的節(jié)點(diǎn)的區(qū)域有效,對(duì)被拖拉的節(jié)點(diǎn)本身是無效的。進(jìn)入目標(biāo)區(qū)域后,拖拉行為會(huì)初始化成設(shè)定的效果。

DataTransfer.effectAllowed 

DataTransfer.effectAllowed屬性設(shè)置本次拖拉中允許的效果。它可能取下面的值。

  • copy:復(fù)制被拖拉的節(jié)點(diǎn)
  • move:移動(dòng)被拖拉的節(jié)點(diǎn)
  • link:創(chuàng)建指向被拖拉節(jié)點(diǎn)的鏈接
  • copyLink:允許copylink
  • copyMove:允許copymove
  • linkMove:允許linkmove
  • all:允許所有效果
  • none:無法放下被拖拉的節(jié)點(diǎn)
  • uninitialized:默認(rèn)值,等同于all

如果某種效果是不允許的,用戶就無法在目標(biāo)節(jié)點(diǎn)中達(dá)成這種效果。

這個(gè)屬性與dropEffect屬性是同一件事的兩個(gè)方面。前者設(shè)置被拖拉的節(jié)點(diǎn)允許的效果,后者設(shè)置接受拖拉的區(qū)域的效果,它們往往配合使用。

dragstart事件的監(jiān)聽函數(shù),可以用來設(shè)置這個(gè)屬性。其他事件的監(jiān)聽函數(shù)里面設(shè)置這個(gè)屬性是無效的。

source.addEventListener('dragstart', function (e) {
  e.dataTransfer.effectAllowed = 'move';
});

target.addEventListener('dragover', function (e) {
  e.dataTransfer.dropEffect = 'move';
});

只要dropEffect屬性和effectAllowed屬性之中,有一個(gè)為none,就無法在目標(biāo)節(jié)點(diǎn)上完成drop操作。

DataTransfer.files 

DataTransfer.files屬性是一個(gè) FileList 對(duì)象,包含一組本地文件,可以用來在拖拉操作中傳送。如果本次拖拉不涉及文件,則該屬性為空的 FileList 對(duì)象。

下面就是一個(gè)接收拖拉文件的例子。

// HTML 代碼如下
// <div id="output" style="min-height: 200px;border: 1px solid black;">
//   文件拖拉到這里
// </div>

var div = document.getElementById('output');

div.addEventListener("dragenter", function( event ) {
  div.textContent = '';
  event.stopPropagation();
  event.preventDefault();
}, false);

div.addEventListener("dragover", function( event ) {
  event.stopPropagation();
  event.preventDefault();
}, false);

div.addEventListener("drop", function( event ) {
  event.stopPropagation();
  event.preventDefault();
  var files = event.dataTransfer.files;
  for (var i = 0; i < files.length; i++) {
    div.textContent += files[i].name + ' ' + files[i].size + '字節(jié)\n';
  }
}, false);

上面代碼中,通過dataTransfer.files屬性讀取被拖拉的文件的信息。如果想要讀取文件內(nèi)容,就要使用FileReader對(duì)象。

div.addEventListener('drop', function(e) {
  e.preventDefault();
  e.stopPropagation();

  var fileList = e.dataTransfer.files;
  if (fileList.length > 0) {
    var file = fileList[0];
    var reader = new FileReader();
    reader.onloadend = function(e) {
      if (e.target.readyState === FileReader.DONE) {
        var content = reader.result;
        div.innerHTML = 'File: ' + file.name + '\n\n' + content;
      }
    }
    reader.readAsBinaryString(file);
  }
});

DataTransfer.types 

DataTransfer.types屬性是一個(gè)只讀的數(shù)組,每個(gè)成員是一個(gè)字符串,里面是拖拉的數(shù)據(jù)格式(通常是 MIME 值)。比如,如果拖拉的是文字,對(duì)應(yīng)的成員就是text/plain。

下面是一個(gè)例子,通過檢查dataTransfer屬性的類型,決定是否允許在當(dāng)前節(jié)點(diǎn)執(zhí)行drop操作。

function contains(list, value){
  for (var i = 0; i < list.length; ++i) {
    if(list[i] === value) return true;
  }
  return false;
}

function doDragOver(event) {
  var isLink = contains(event.dataTransfer.types, 'text/uri-list');
  if (isLink) event.preventDefault();
}

上面代碼中,只有當(dāng)被拖拉的節(jié)點(diǎn)有一個(gè)是鏈接時(shí),才允許在當(dāng)前節(jié)點(diǎn)放下。

DataTransfer.items 

DataTransfer.items屬性返回一個(gè)類似數(shù)組的只讀對(duì)象(DataTransferItemList 實(shí)例),每個(gè)成員就是本次拖拉的一個(gè)對(duì)象(DataTransferItem 實(shí)例)。如果本次拖拉不包含對(duì)象,則返回一個(gè)空對(duì)象。

DataTransferItemList 實(shí)例具有以下的屬性和方法。

  • length:返回成員的數(shù)量
  • add(data, type):增加一個(gè)指定內(nèi)容和類型(比如text/htmltext/plain)的字符串作為成員
  • add(file)add方法的另一種用法,增加一個(gè)文件作為成員
  • remove(index):移除指定位置的成員
  • clear():移除所有的成員

DataTransferItem 實(shí)例具有以下的屬性和方法。

  • kind:返回成員的種類(string還是file)。
  • type:返回成員的類型(通常是 MIME 值)。
  • getAsFile():如果被拖拉是文件,返回該文件,否則返回null。
  • getAsString(callback):如果被拖拉的是字符串,將該字符傳入指定的回調(diào)函數(shù)處理。該方法是異步的,所以需要傳入回調(diào)函數(shù)。

下面是一個(gè)例子。

div.addEventListener('drop', function (e) {
  e.preventDefault();
  if (e.dataTransfer.items != null) {
    for (var i = 0; i < e.dataTransfer.items.length; i++) {
      console.log(e.dataTransfer.items[i].kind + ': ' + e.dataTransfer.items[i].type);
    }
  }
});

DataTransfer 的實(shí)例方法 

DataTransfer.setData() 

DataTransfer.setData()方法用來設(shè)置拖拉事件所帶有的數(shù)據(jù)。該方法沒有返回值。

event.dataTransfer.setData('text/plain', 'Text to drag');

上面代碼為當(dāng)前的拖拉事件加入純文本數(shù)據(jù)。

該方法接受兩個(gè)參數(shù),都是字符串。第一個(gè)參數(shù)表示數(shù)據(jù)類型(比如text/plain),第二個(gè)參數(shù)是具體數(shù)據(jù)。如果指定類型的數(shù)據(jù)在dataTransfer屬性不存在,那么這些數(shù)據(jù)將被加入,否則原有的數(shù)據(jù)將被新數(shù)據(jù)替換。

如果是拖拉文本框或者拖拉選中的文本,會(huì)默認(rèn)將對(duì)應(yīng)的文本數(shù)據(jù),添加到dataTransfer屬性,不用手動(dòng)指定。

<div draggable="true">
  aaa
</div>

上面代碼中,拖拉這個(gè)<div>元素會(huì)自動(dòng)帶上文本數(shù)據(jù)aaa。

使用setData方法,可以替換到原有數(shù)據(jù)。

<div
  draggable="true"
  ondragstart="event.dataTransfer.setData('text/plain', 'bbb')"
>
  aaa
</div>

上面代碼中,拖拉數(shù)據(jù)實(shí)際上是bbb,而不是aaa。

下面是添加其他類型的數(shù)據(jù)。由于text/plain是最普遍支持的格式,為了保證兼容性,建議最后總是保存一份純文本格式的數(shù)據(jù)。

var dt = event.dataTransfer;

// 添加鏈接
dt.setData('text/uri-list', 'http://www.example.com');
dt.setData('text/plain', 'http://www.example.com');

// 添加 HTML 代碼
dt.setData('text/html', 'Hello there, <strong>stranger</strong>');
dt.setData('text/plain', 'Hello there, <strong>stranger</strong>');

// 添加圖像的 URL
dt.setData('text/uri-list', imageurl);
dt.setData('text/plain', imageurl);

可以一次提供多種格式的數(shù)據(jù)。

var dt = event.dataTransfer;
dt.setData('application/x-bookmark', bookmarkString);
dt.setData('text/uri-list', 'http://www.example.com');
dt.setData('text/plain', 'http://www.example.com');

上面代碼中,通過在同一個(gè)事件上面,存放三種類型的數(shù)據(jù),使得拖拉事件可以在不同的對(duì)象上面,drop不同的值。注意,第一種格式是一個(gè)自定義格式,瀏覽器默認(rèn)無法讀取,這意味著,只有某個(gè)部署了特定代碼的節(jié)點(diǎn),才可能drop(讀取到)這個(gè)數(shù)據(jù)。

DataTransfer.getData() 

DataTransfer.getData()方法接受一個(gè)字符串(表示數(shù)據(jù)類型)作為參數(shù),返回事件所帶的指定類型的數(shù)據(jù)(通常是用setData方法添加的數(shù)據(jù))。如果指定類型的數(shù)據(jù)不存在,則返回空字符串。通常只有drop事件觸發(fā)后,才能取出數(shù)據(jù)。

下面是一個(gè)drop事件的監(jiān)聽函數(shù),用來取出指定類型的數(shù)據(jù)。

function onDrop(event) {
  var data = event.dataTransfer.getData('text/plain');
  event.target.textContent = data;
  event.preventDefault();
}

上面代碼取出拖拉事件的文本數(shù)據(jù),將其替換成當(dāng)前節(jié)點(diǎn)的文本內(nèi)容。注意,這時(shí)還必須取消瀏覽器的默認(rèn)行為,因?yàn)榧偃缬脩敉侠氖且粋€(gè)鏈接,瀏覽器默認(rèn)會(huì)在當(dāng)前窗口打開這個(gè)鏈接。

getData方法返回的是一個(gè)字符串,如果其中包含多項(xiàng)數(shù)據(jù),就必須手動(dòng)解析。

function doDrop(event) {
  var lines = event.dataTransfer.getData('text/uri-list').split('\n');
  for (let line of lines) {
    let link = document.createElement('a');
    link.href = line;
    link.textContent = line;
    event.target.appendChild(link);
  }
  event.preventDefault();
}

上面代碼中,getData方法返回的是一組鏈接,就必須自行解析。

類型值指定為URL,可以取出第一個(gè)有效鏈接。

var link = event.dataTransfer.getData('URL');

下面的例子是從多種類型的數(shù)據(jù)里面取出數(shù)據(jù)。

function doDrop(event) {
  var types = event.dataTransfer.types;
  var supportedTypes = ['text/uri-list', 'text/plain'];
  types = supportedTypes.filter(function (value) { types.includes(value) });
  if (types.length) {
    var data = event.dataTransfer.getData(types[0]);
  }
  event.preventDefault();
}

DataTransfer.clearData() 

DataTransfer.clearData()方法接受一個(gè)字符串(表示數(shù)據(jù)類型)作為參數(shù),刪除事件所帶的指定類型的數(shù)據(jù)。如果沒有指定類型,則刪除所有數(shù)據(jù)。如果指定類型不存在,則調(diào)用該方法不會(huì)產(chǎn)生任何效果。

event.dataTransfer.clearData('text/uri-list');

上面代碼清除事件所帶的text/uri-list類型的數(shù)據(jù)。

該方法不會(huì)移除拖拉的文件,因此調(diào)用該方法后,DataTransfer.types屬性可能依然會(huì)返回Files類型(前提是存在文件拖拉)。

注意,該方法只能在dragstart事件的監(jiān)聽函數(shù)之中使用,因?yàn)檫@是拖拉操作的數(shù)據(jù)唯一可寫的時(shí)機(jī)。

DataTransfer.setDragImage() 

拖動(dòng)過程中(dragstart事件觸發(fā)后),瀏覽器會(huì)顯示一張圖片跟隨鼠標(biāo)一起移動(dòng),表示被拖動(dòng)的節(jié)點(diǎn)。這張圖片是自動(dòng)創(chuàng)造的,通常顯示為被拖動(dòng)節(jié)點(diǎn)的外觀,不需要自己動(dòng)手設(shè)置。

DataTransfer.setDragImage()方法可以自定義這張圖片。它接受三個(gè)參數(shù)。第一個(gè)是<img>節(jié)點(diǎn)或者<canvas>節(jié)點(diǎn),如果省略或?yàn)?code>null,則使用被拖動(dòng)的節(jié)點(diǎn)的外觀;第二個(gè)和第三個(gè)參數(shù)為鼠標(biāo)相對(duì)于該圖片左上角的橫坐標(biāo)和縱坐標(biāo)。

下面是一個(gè)例子。

/* HTML 代碼如下
 <div id="drag-with-image" class="dragdemo" draggable="true">
   drag me
 </div>
*/

var div = document.getElementById('drag-with-image');
div.addEventListener('dragstart', function (e) {
  var img = document.createElement('img');
  img.src = 'http://path/to/img';
  e.dataTransfer.setDragImage(img, 0, 0);
}, false);


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)