web前端-在迷惘中的探索HTML5(四)HTML5之拖動

html5出現(xiàn)了很多比較好的應(yīng)用秽梅,今天我們來講講關(guān)于元素拖動的抹蚀。

前言

關(guān)于拖動,我們應(yīng)該理解什么是拖動源和放置目標(biāo)企垦?這里上圖說明:

在html5拖放出來之前况鸣,有過一種原始自己定義來實(shí)現(xiàn)類似拖動的效果:

  1. 為拖動源注冊鼠標(biāo)點(diǎn)擊事件
  2. 為拖動源注冊鼠標(biāo)移動事件,判斷是否先點(diǎn)擊過拖動源竹观,如點(diǎn)擊過則元素通過絕對定位并跟隨鼠標(biāo)移動镐捧。
  3. 經(jīng)過放置目標(biāo)后將拖動源對象加載到放置目標(biāo)的子節(jié)點(diǎn)下

這種原始拖動實(shí)在是,不說了上代碼自己看:(請自行準(zhǔn)備jquery)

<!doctype html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <script type="text/javascript" src="jquery-1.9.1.js"></script>
</head>
<body>
 <div id="leftDiv" style="width:300px;height: 300px;float:left;border: 1px solid #f00;">
  <div id="inner" style="width:100px;height: 100px;float:left;background:yellow;"></div>
 </div>
 <div id="rightDiv" style="width:300px;height: 300px;float:left;border: 1px solid #f00;margin-left:300px;"></div>
 
 <script>
  //鼠標(biāo)拖拽
  $(function(){
   register();
   var startInner = 0;//0-初始臭增、1-拖拽懂酱、2-結(jié)束
   var index = 0;
   function register(){
    $('#inner').mousedown(function(event) {
     /* Act on the event */
     index++;
     var $cloneInner = $('#inner').clone();
     $cloneInner.attr('id','cloneInner' + index);
     $cloneInner.css('background', '#000');
     $(document.body).append($cloneInner);
     $cloneInner.css({
      position:'absolute',
      left:event.pageX - event.currentTarget.offsetWidth/2 + 'px',
      top:event.pageY - event.currentTarget.offsetHeight/2 + 'px'
     });
     startInner = 1;
    });
    $(document).on('mousemove', function(event) {
     /* Act on the event */
     if(startInner!=1){
      return;
     }
     var $cloneInner = $('#cloneInner' + index);
     $cloneInner.css({
      // position:'absolute',
      left:event.pageX - $('#inner')[0].offsetWidth/2 + 'px',
      top:event.pageY - $('#inner')[0].offsetHeight/2 + 'px'
     });
    });
    $(document).on('mouseup', function(event) {
     if(startInner!=1){
      return;
     }
     if(event.pageX > $('#rightDiv').offset().left&&event.pageY > $('#rightDiv').offset().top&&event.pageX < $('#rightDiv').offset().left + $('#rightDiv').width()&&event.pageY < $('#rightDiv').offset().top + $('#rightDiv').height()){//event.target.id == 'rightDiv'
      $('#cloneInner' + index).css('position','static');
      $('#cloneInner' + index).css('float','left');
      $('#cloneInner' + index).appendTo($('#rightDiv'));
     }else{
      $('#cloneInner' + index).remove();
     }
     startInner = 2;
    });
   }
  })
 </script>
</body>
</html>

而現(xiàn)在html5的拖放機(jī)制:

  1. 使用新增的屬性設(shè)定拖動源可以拖放
  2. 使用新增的拖放事件,禁止默認(rèn)行為誊抛,傳遞拖放信息
  3. 使用新增的拖放結(jié)束事件列牺,在完成拖放后改變dom結(jié)構(gòu)

二者一對比,就知道哪個(gè)好

拖放api

拖放屬性與對象:

draggable 屬性

draggable 屬性:設(shè)置當(dāng)前元素是否可以拖放拗窃,draggable=true/false瞎领,設(shè)定為可拖拽后當(dāng)前元素可以拖拽泌辫,但是你以為可以亂放嗎?所有經(jīng)過的區(qū)域默認(rèn)行為會組織你進(jìn)行放置九默,你會看到拖動源上顯示一個(gè)禁止放置的圖標(biāo)震放。

<div title="拖拽我" draggable="true">拖我</div>
DataTransfer 對象

DataTransfer 對象:拖拽對象用來傳遞的媒介,使用一般為Event.dataTransfer驼修。在進(jìn)行拖放操作時(shí)殿遂,DataTransfer對象用來保存被拖動的數(shù)據(jù)。它可以保存一項(xiàng)或多項(xiàng)數(shù)據(jù)乙各、一種或者多種數(shù)據(jù)類型墨礁,其在所有的拖動事件中都是可用的,但是不能單獨(dú)創(chuàng)建耳峦。
其常用方法:
setData(type,data):設(shè)定本次拖拽的參數(shù)恩静,為一個(gè)給定的類型設(shè)置數(shù)據(jù)。如果該數(shù)據(jù)類型不存在蹲坷,它將添加到的末尾蜕企,這樣類型列表中的最后一個(gè)項(xiàng)目將是新的格式。如果已經(jīng)存在的數(shù)據(jù)類型冠句,替換相同的位置的現(xiàn)有數(shù)據(jù)轻掩。

參數(shù):
type-要添加的數(shù)據(jù)類型.自定義
data-要添加的數(shù)據(jù).

getData(type):獲取本次拖拽的參數(shù),檢索(取得)給定類型的數(shù)據(jù)懦底,如果給定類型的數(shù)據(jù)不存在或者數(shù)據(jù)轉(zhuǎn)存(data transfer)沒有包涵數(shù)據(jù)唇牧,方法將返回一個(gè)空字符串。

參數(shù):
type-要獲取的數(shù)據(jù)類型.

setDragImage(imgElement,offsetX,offsetY):自定義一個(gè)你拖動時(shí)會期望出現(xiàn)的圖片聚唐。大多數(shù)情況下丐重,這項(xiàng)不用設(shè)置,因?yàn)楸煌蟿拥墓?jié)點(diǎn)被創(chuàng)建成默認(rèn)圖片杆查。

參數(shù):
image-要用作拖動反饋圖像元素扮惦。
x-圖像內(nèi)的水平偏移量.
y-圖像內(nèi)的垂直偏移量.

其常用屬性:
dropEffect:設(shè)置實(shí)際的放置效果,它應(yīng)該始終設(shè)置成effectAllowed的可能值之一 亲桦。對于dragstart, dragdragleave事件崖蜜,dropEffect會被初始化為 “none”。任何有效的值都可以用來設(shè)置dropEffect客峭,這是這些設(shè)置的值沒有任何效果
可能的值:
? copy: 復(fù)制到新的位置
? move: 移動到新的位置.
? link: 建立一個(gè)源位置到新位置的鏈接.
? none: 禁止放置(禁止任何操作).
分配任何其他值時(shí)不會有任何影響并且保留舊值
effectAllowed:用來指定拖動時(shí)被允許的效果豫领。你可以在dragstart事件中設(shè)置拖動源數(shù)據(jù)時(shí)期望的動作效果,同時(shí)在dragenterdragover事件中為目標(biāo)設(shè)置期望的效果舔琅。這些值在其他的事件中沒有任何作用等恐。
可能的值:
? copy: 復(fù)制到新的位置.
? move:移動到新的位置 .
? link:建立一個(gè)源位置到新位置的鏈接.
? copyLink: 允許復(fù)制或者鏈接.
? copyMove: 允許復(fù)制或者移動.
? linkMove: 允許鏈接或者移動.
? all: 允許所有的操作.
? none: 禁止所有操作.
? uninitialized: 缺省值(默認(rèn)值), 相當(dāng)于 all.
分配任何其他值時(shí)不會有任何影響并且保留舊值

拖放事件

ondragstart事件:綁定給拖拽源,當(dāng)拖拽源開始被拖拽的時(shí)候觸發(fā)的事件,在這個(gè)事件中课蔬,監(jiān)聽器將設(shè)置與這次拖拽相關(guān)的信息囱稽,例如拖動的數(shù)據(jù)和圖像。同時(shí)其也是在響應(yīng)函數(shù)中唯一可以setData的事件二跋。參考:拖拽操作

ondrap事件:綁定給拖拽源战惊,在拖拽源拖動的過程中不斷調(diào)用相應(yīng)的函數(shù)。

ondragend事件:綁定給拖拽源同欠,當(dāng)拖拽完成后觸發(fā)的事件,不管操作成功與否横缔。

ondragenter事件:綁定給放置目標(biāo)铺遂,當(dāng)拖拽源剛進(jìn)入放置目標(biāo)元素的時(shí)候觸發(fā)的事件,這個(gè)事件的監(jiān)聽器需要指明是否允許在這個(gè)區(qū)域釋放鼠標(biāo)茎刚。如果沒有設(shè)置監(jiān)聽器襟锐,或者監(jiān)聽器沒有進(jìn)行操作,則默認(rèn)不允許釋放膛锭。如果你想要通過類似高亮或插入標(biāo)記等方式來告知用戶此處可以釋放粮坞,就需要監(jiān)聽這個(gè)事件。

ondragover事件:綁定給放置目標(biāo)初狰,拖拽源在放置目標(biāo)元素上拖動的時(shí)候不斷觸發(fā)的事件莫杈,其發(fā)生的操作和ondragenter事件一樣。

ondrop事件:綁定給放置目標(biāo)奢入,在拖動結(jié)束的時(shí)候拖拽源在放置目標(biāo)元素上時(shí)觸發(fā)的事件筝闹,用來響應(yīng)接收拖拽源的數(shù)據(jù)并插入到放置目標(biāo)上。這個(gè)事件只有在需要時(shí)才觸發(fā)腥光。當(dāng)用戶取消了拖拽操作時(shí)將不觸發(fā)关顷,例如按下了Escape(ESC)按鍵,或鼠標(biāo)在非可釋放目標(biāo)上釋放了按鍵武福。

dragleave事件:綁定給放置目標(biāo)议双,當(dāng)拖拽源的鼠標(biāo)離開元素時(shí)觸發(fā)。用于需要將作為可釋放反饋的高亮或插入標(biāo)記去除捉片。

Event.preventDefault()方法:阻止默認(rèn)的些事件方法等執(zhí)行平痰。在ondragover中一定要執(zhí)行preventDefault(),否則ondrop事件不會被觸發(fā)伍纫。另外觉增,如果是從其他應(yīng)用軟件或是文件中拖東西進(jìn)來,尤其是圖片的時(shí)候翻斟,默認(rèn)的動作是顯示這個(gè)圖片或是相關(guān)信息逾礁,并不是真的執(zhí)行drop。此時(shí)需要用用document的ondragover事件把它直接干掉。

拖放實(shí)現(xiàn)步驟

處理拖放通常有以下幾個(gè)步驟:

  1. 定義可拖動目標(biāo)嘹履。將我們希望拖動的元素的draggable屬性設(shè)為true腻扇。
  2. 定義拖拽源拖動時(shí)的數(shù)據(jù),可能為多種不同格式砾嫉。例如幼苛,文本型數(shù)據(jù)會包含被拖動文本的字符串。參考:dataTransfer對象
  3. (可選)自定義拖動過程中鼠標(biāo)指針旁邊會出現(xiàn)的拖動反饋圖片焕刮。如果未設(shè)定舶沿,默認(rèn)圖片會基于鼠標(biāo)按鈕按下的元素(正在被拖動的元素)來自動生成。
  4. 允許設(shè)置拖拽效果配并。有三種效果可以選擇:copy 用來指明拖拽的數(shù)據(jù)將從當(dāng)前位置復(fù)制到釋放的位置括荡;move 用來指明被拖拽的數(shù)據(jù)將被移動;link 用來指明將在源位置與投放位置之間建立某些形式的關(guān)聯(lián)或連接溉旋。在拖拽的過程中畸冲,可以修改拖拽效果來指明在某些位置允許某些效果。如果允許观腊,你將可以把數(shù)據(jù)釋放到那個(gè)位置邑闲。
  5. 定義放置區(qū)域。默認(rèn)情況下梧油,瀏覽器阻止任何東西向HTML元素放置拖拽的發(fā)生苫耸。要使一個(gè)元素稱為可放置區(qū)域,需要阻止瀏覽器的默認(rèn)行為儡陨,也就是要監(jiān)聽dragenter 和 dragover 事件使用Event.preventDefault()鲸阔。
  6. 在drop發(fā)生時(shí)做一些事情。你可能想要獲取拖拽目標(biāo)攜帶的數(shù)據(jù)并做某些相應(yīng)的事情迄委。

步驟圖解:

代碼實(shí)現(xiàn)

注意:一定要好好看拖動api

因?yàn)楹芎唵魏稚福圆辉敿?xì)說了,上代碼自己看:(請自行準(zhǔn)備jquery)

<!doctype html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <script type="text/javascript" src="jquery-1.12.3.min.js"></script>
</head>
<body>
 <div style="width:200px;height:200px;border: 1px solid #000;">
  <div id="tuodong1" style="width:100px;height:100px;background:yellow" draggable="true"></div>
  <div id="tuodong2" style="width:100px;height:100px;background:yellow" draggable="true"></div>
 </div>
 <!-- <div id="tuodong" style="width:100px;height:100px;background:yellow" draggable="true"></div> -->

 <div id="mubiaoquyu" style="width:500px;height:500px;border: 1px solid #000;"></div>
 <script>
    // 監(jiān)聽dragstart事件叙身,設(shè)置拖動信息
  $("div div").on("dragstart",function(e){
   var tuodongId = event.currentTarget.id;
   event.dataTransfer.setData("dataId",tuodongId);//dataTransfer是信息傳遞對象
  });
  // 監(jiān)聽drop事件渔扎,獲取拖動信息
  $("div").on("drop",function(e){
   //獲取到當(dāng)前div對象將dom對象塞入div中
   var div = event.currentTarget;
   var dataId = event.dataTransfer.getData("dataId");
   var divDom = document.getElementById(dataId);
   div.appendChild(divDom);
  });
  // 監(jiān)聽dragover事件,阻止默認(rèn)行為允許放置
  $("div").on("dragover",function(e){
   event.preventDefault();
  });
 </script>
</body>
</html>

小結(jié):

到此關(guān)于html5的拖動功能就介紹完畢了信轿,這個(gè)東西其實(shí)很簡單晃痴,會者不難,難者不會财忽,但是很多教程把它說的很混亂倘核,所以特來正正風(fēng)氣。

提示:后面還有精彩敬請期待即彪,請大家關(guān)注我的CSDN博文:儂姝沁兒紧唱,或者我的簡書專題:web前端。如有意見可以進(jìn)行評論,每一條評論我都會認(rèn)真對待漏益。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蛹锰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子绰疤,更是在濱河造成了極大的恐慌铜犬,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件轻庆,死亡現(xiàn)場離奇詭異癣猾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)余爆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門纷宇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人龙屉,你說我怎么就攤上這事呐粘÷祝” “怎么了转捕?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長唆垃。 經(jīng)常有香客問我五芝,道長,這世上最難降的妖魔是什么辕万? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任枢步,我火速辦了婚禮,結(jié)果婚禮上渐尿,老公的妹妹穿的比我還像新娘醉途。我一直安慰自己,他們只是感情好砖茸,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布隘擎。 她就那樣靜靜地躺著,像睡著了一般凉夯。 火紅的嫁衣襯著肌膚如雪货葬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天劲够,我揣著相機(jī)與錄音震桶,去河邊找鬼。 笑死征绎,一個(gè)胖子當(dāng)著我的面吹牛蹲姐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼淤堵,長吁一口氣:“原來是場噩夢啊……” “哼寝衫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拐邪,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤慰毅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后扎阶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體汹胃,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年东臀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了着饥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,626評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡惰赋,死狀恐怖宰掉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赁濒,我是刑警寧澤轨奄,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站拒炎,受9級特大地震影響挪拟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜击你,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一玉组、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧丁侄,春花似錦惯雳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至户辱,卻和暖如春鸵钝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背庐镐。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工恩商, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人必逆。 一個(gè)月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓怠堪,卻偏偏與公主長得像揽乱,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子粟矿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評論 2 348

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