HTML5拖放API附帶示例

拖放(Drag 和 drop)是HTML5標準的組成部分

拖放

拖放是一種常見的特性辟犀,即抓取對象以后拖放到其他位置油湖。在 HTML5 中饰豺,拖放是標準的一部分晦闰,任何元素都可以被拖放嚣鄙。

瀏覽器支持

Internet Explorer 9 + 吻贿、Firefox、Opera 12 + 哑子、Chrome 以及 Safari 5 + 支持拖放舅列。

拖放API

draggable屬性

如果希望一個網(wǎng)頁元素可以被拖動,只需要將他的draggable屬性設置為true卧蜓,這個元素就可以拖動了帐要。

<div draggable="true">拖動我試試</div>

事件

拖動的過程會觸發(fā)許多事件,主要有下面這些:

  • dragstart:網(wǎng)頁元素開始拖動時觸發(fā)弥奸。
  • drag:被拖動的元素在拖動過程中持續(xù)觸發(fā)榨惠。
  • dragenter:被拖動的元素進入目標元素時觸發(fā),應在目標元素監(jiān)聽該事件盛霎。
  • dragleave:被拖動的元素離開目標元素時觸發(fā)赠橙,應在目標元素監(jiān)聽該事件。
  • dragover:被拖動元素停留在目標元素之中時持續(xù)觸發(fā)愤炸,應在目標元素監(jiān)聽該事件期揪。
  • drop:被拖動元素或從文件系統(tǒng)選中的文件,拖放落下時觸發(fā)规个。
  • dragend:網(wǎng)頁元素拖動結(jié)束時觸發(fā)凤薛。

以上函數(shù)均可以指定回調(diào)函數(shù):

draggableElement.addEventListener('dragstart', function(e) {
    alert('拖放開始姓建!')
    console.log(e);
});

拖動過程中,鼠標移動事件將不會被觸發(fā)枉侧。

dataTransfer對象

拖動過程中引瀑,回調(diào)函數(shù)接受的事件參數(shù),有一個dataTransfer屬性榨馁。它指向一個對象憨栽,包含了與拖動相關的各種信息。
dataTransfer對象的屬性:

  • dropEffect:拖放的操作類型翼虫,決定了瀏覽器如何顯示鼠標形狀屑柔,可能的值為copy、move珍剑、link和none掸宛。
  • effectAllowed:指定所允許的操作,可能的值為copy招拙、move唧瘾、link、copyLink别凤、copyMove饰序、linkMove、all规哪、none和uninitialized(默認值求豫,等同于all,即允許一切操作)诉稍。
  • files:包含一個FileList對象蝠嘉,表示拖放所涉及的文件,主要用于處理從文件系統(tǒng)拖入瀏覽器的文件杯巨。
  • types:儲存在DataTransfer對象的數(shù)據(jù)的類型蚤告。

dataTransfer對象的方法:

  • setData(format, data):在dataTransfer對象上儲存數(shù)據(jù)。第一個參數(shù)format用來指定儲存的數(shù)據(jù)類型服爷,比如text杜恰、url、text/html等层扶。
  • getData(format):從dataTransfer對象取出數(shù)據(jù)箫章。
  • clearData(format):清除dataTransfer對象所儲存的數(shù)據(jù)烙荷。如果指定了format參數(shù)镜会,則只清除該格式的數(shù)據(jù),否則清除所有數(shù)據(jù)终抽。
  • setDragImage(imgElement, x, y):指定拖動過程中顯示的圖像戳表。默認情況下桶至,許多瀏覽器顯示一個被拖動元素的半透明版本。參數(shù)imgElement必須是一個圖像元素匾旭,而不是指向圖像的路徑镣屹,參數(shù)x和y表示圖像相對于鼠標的位置。
draggableElement.addEventListener('dragstart', function(event) {
    event.dataTransfer.setData('text', 'Hello World!');
});

上面代碼在拖動開始時价涝,在dataTransfer對象上儲存一條文本信息女蜈,內(nèi)容為“Hello World!”色瘩。當拖放結(jié)束時伪窖,可以用getData方法取出這條信息。

dataTransfer對象允許在其上存儲數(shù)據(jù)居兆,這使得在被拖動元素與目標元素之間傳送信息成為可能覆山。

實例

簡單拖放

/* html */
<ul id="drag-elements">
  <li id="A" draggable="true"><img src="1.jpg" alt="" /></li>
  <li id="B" draggable="true"><img src="2.jpg" alt="" /></li>
  <li id="C" draggable="true"><img src="3.jpg" alt="" /></li>
  <li id="D" draggable="true"><img src="4.jpg" alt="" /></li>
  <li id="E" draggable="true"><img src="5.jpg" alt="" /></li>
  <li id="F" draggable="true"><img src="6.jpg" alt="" /></li>
  <li id="G" draggable="true"><img src="7.jpg" alt="" /></li>
  <li id="H" draggable="true"><img src="8.jpg" alt="" /></li>
</ul>

/* css */
ul {
  margin:0 auto;
  width:800px;
}
ul:after{
  content:"";
  display:block;
  clear:both;
}
li {
  width:200px;
  height:125px;
  float:left;
  background-color:#CCC;
  text-align:center;
  line-height:120px;
  font-size:50px;
  color:#F60;
}
.dragStart img {
  width:200px;
  height:125px;
}
/* js */
var dragElements = document.querySelectorAll('#drag-elements li');
var elementDragged = null;
for (var i = 0; i < dragElements.length; i++) {
  dragElements[i].addEventListener('dragstart', function (e) {
    e.dataTransfer.setData('text', this.id);
    elementDragged = this;
  });
  dragElements[i].addEventListener('dragover', function (e) {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'move';
    elementDragged.setAttribute('class', 'dragStart');
    return false;
  });
  dragElements[i].addEventListener('dragenter', function(e) {
    e.preventDefault();
    e.stopPropagation();
    if (this.id != elementDragged.id) {
      var tempInnerHtml = this.innerHTML;
      this.innerHTML = elementDragged.innerHTML;
      elementDragged.innerHTML = tempInnerHtml;
      elementDragged.removeAttribute('class');
      elementDragged = this;
    }
  });
  dragElements[i].addEventListener('dragleave', function(e) {
    e.preventDefault();
    e.stopPropagation();
    if (this.id != elementDragged.id) {
      this.removeAttribute('class');
    }
  });
  dragElements[i].addEventListener('drop', function (e) {
    e.preventDefault();
    e.stopPropagation();  
    var targetId = e.dataTransfer.getData('text');
    elementDragged.removeAttribute('class');
    return false;
  });
  dragElements[i].addEventListener('dragend', function (e) {
    elementDragged = null;
  });
};

拖放網(wǎng)元素

/* html */
<ul id="drag-elements">
    <li draggable="true">A</li>
    <li draggable="true">B</li>
    <li draggable="true">C</li>
</ul>
<ul id="drop-target"></ul>

/* css */
ul{
    min-height:100px;
    background-color:#EEE;
    margin:20px;
    padding: 0;
}
ul li{
    background-color:#CCC;
    padding:10px;
    margin-bottom:10px;
    list-style: none;
}

/* js */
// 獲取dom元素
var target = document.querySelector('#drop-target');
var dragElements = document.querySelectorAll('#drag-elements li');

// 定義變量跟蹤被拖動的元素
var elementDragged = null;

// 對可以拖放的元素綁定 dragstart 和 dragend 事件
for (var i = 0; i < dragElements.length; i++) {
  dragElements[i].addEventListener('dragstart', function(e) {
    e.dataTransfer.setData('text', this.innerHTML);
    elementDragged = this;
  });
  dragElements[i].addEventListener('dragend', function(e) {
    elementDragged = null;
  });
}

// 向目標元素綁定 dragover 事件,來處理元素拖動進入目標元素之后的事情
target.addEventListener('dragover', function(e) {
  e.preventDefault();
  e.dataTransfer.dropEffect = 'move';
  return false;
});

// 最后定義目標元素的 drop事件,將被拖動元素從原來的位置刪除
target.addEventListener('drop', function(e) {
  e.preventDefault();
  e.stopPropagation();
  this.innerHTML = 'Dropped ' + e.dataTransfer.getData('text');
  document.querySelector('#drag-elements').removeChild(elementDragged);
  return false;
});

拖放文件

/* html */
<div id="target" title="拖動文件到這里">
  <div id="content"></div>
</div>

/* css */
#target{
  margin:10px;
  min-height:100px;
  max-height:600px;
  background-color:#EEE;
  border-radius:5px;
  overflow:auto;
}
#content{
  padding:10px;
  font-size:18px;
  line-height:25px;
}

/* js */
// 首先獲取拖動的目標元素和內(nèi)容展示區(qū)域
var target = document.querySelector('#target');
var contentDiv = document.querySelector('#content');

// 然后定義目標元素的dragover事件,定義了當文件進入目標元素后要做的事情
target.addEventListener('dragover', function(e) {
  e.preventDefault();
  e.stopPropagation();
  e.dataTransfer.dropEffect = 'copy';
  return false;
});

// 最后定義目標元素的drop事件,展示文件內(nèi)容
target.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;
        contentDiv.innerHTML = "File: " + file.name + "\n\n" + content;
      }
    }
    reader.readAsBinaryString(file);
  }
});
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市泥栖,隨后出現(xiàn)的幾起案子簇宽,更是在濱河造成了極大的恐慌,老刑警劉巖吧享,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件魏割,死亡現(xiàn)場離奇詭異,居然都是意外死亡耙蔑,警方通過查閱死者的電腦和手機见妒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來甸陌,“玉大人须揣,你說我怎么就攤上這事∏恚” “怎么了耻卡?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長牲尺。 經(jīng)常有香客問我卵酪,道長,這世上最難降的妖魔是什么谤碳? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任溃卡,我火速辦了婚禮,結(jié)果婚禮上蜒简,老公的妹妹穿的比我還像新娘瘸羡。我一直安慰自己,他們只是感情好搓茬,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布犹赖。 她就那樣靜靜地躺著队他,像睡著了一般。 火紅的嫁衣襯著肌膚如雪峻村。 梳的紋絲不亂的頭發(fā)上麸折,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機與錄音粘昨,去河邊找鬼垢啼。 笑死,一個胖子當著我的面吹牛张肾,可吹牛的內(nèi)容都是我干的膊夹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼捌浩,長吁一口氣:“原來是場噩夢啊……” “哼放刨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起尸饺,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤进统,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后浪听,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體螟碎,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年迹栓,在試婚紗的時候發(fā)現(xiàn)自己被綠了掉分。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡克伊,死狀恐怖酥郭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情愿吹,我是刑警寧澤不从,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站犁跪,受9級特大地震影響椿息,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜坷衍,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一寝优、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧枫耳,春花似錦乏矾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至仑最,卻和暖如春扔役,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背警医。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工亿胸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人预皇。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓侈玄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親吟温。 傳聞我的和親對象是個殘疾皇子序仙,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容