html5出現(xiàn)了很多比較好的應(yīng)用秽梅,今天我們來講講關(guān)于元素拖動的抹蚀。
前言
關(guān)于拖動,我們應(yīng)該理解什么是拖動源和放置目標(biāo)企垦?這里上圖說明:
在html5拖放出來之前况鸣,有過一種原始自己定義來實(shí)現(xiàn)類似拖動的效果:
- 為拖動源注冊鼠標(biāo)點(diǎn)擊事件
- 為拖動源注冊鼠標(biāo)移動事件,判斷是否先點(diǎn)擊過拖動源竹观,如點(diǎn)擊過則元素通過絕對定位并跟隨鼠標(biāo)移動镐捧。
- 經(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ī)制:
- 使用新增的屬性設(shè)定拖動源可以拖放
- 使用新增的拖放事件,禁止默認(rèn)行為誊抛,傳遞拖放信息
- 使用新增的拖放結(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
, drag
和dragleave
事件崖蜜,dropEffect
會被初始化為 “none”。任何有效的值都可以用來設(shè)置dropEffect
客峭,這是這些設(shè)置的值沒有任何效果
可能的值:
? copy
: 復(fù)制到新的位置
? move
: 移動到新的位置.
? link
: 建立一個(gè)源位置到新位置的鏈接.
? none
: 禁止放置(禁止任何操作).
分配任何其他值時(shí)不會有任何影響并且保留舊值
effectAllowed
:用來指定拖動時(shí)被允許的效果豫领。你可以在dragstart
事件中設(shè)置拖動源數(shù)據(jù)時(shí)期望的動作效果,同時(shí)在dragenter
和dragover
事件中為目標(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è)步驟:
- 定義可拖動目標(biāo)嘹履。將我們希望拖動的元素的draggable屬性設(shè)為true腻扇。
- 定義拖拽源拖動時(shí)的數(shù)據(jù),可能為多種不同格式砾嫉。例如幼苛,文本型數(shù)據(jù)會包含被拖動文本的字符串。參考:dataTransfer對象
- (可選)自定義拖動過程中鼠標(biāo)指針旁邊會出現(xiàn)的拖動反饋圖片焕刮。如果未設(shè)定舶沿,默認(rèn)圖片會基于鼠標(biāo)按鈕按下的元素(正在被拖動的元素)來自動生成。
- 允許設(shè)置拖拽效果配并。有三種效果可以選擇:copy 用來指明拖拽的數(shù)據(jù)將從當(dāng)前位置復(fù)制到釋放的位置括荡;move 用來指明被拖拽的數(shù)據(jù)將被移動;link 用來指明將在源位置與投放位置之間建立某些形式的關(guān)聯(lián)或連接溉旋。在拖拽的過程中畸冲,可以修改拖拽效果來指明在某些位置允許某些效果。如果允許观腊,你將可以把數(shù)據(jù)釋放到那個(gè)位置邑闲。
- 定義放置區(qū)域。默認(rèn)情況下梧油,瀏覽器阻止任何東西向HTML元素放置拖拽的發(fā)生苫耸。要使一個(gè)元素稱為可放置區(qū)域,需要阻止瀏覽器的默認(rèn)行為儡陨,也就是要監(jiān)聽dragenter 和 dragover 事件使用Event.preventDefault()鲸阔。
- 在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)真對待漏益。