淺談js原生拖放
可拖動(dòng)
網(wǎng)頁(yè)中的圖像、鏈接和文本是瀏覽器默認(rèn)可以被拖動(dòng)的,HTML5 為所有的HTML元素都提供了一個(gè)draggable屬性,當(dāng)這個(gè)屬性的值為true的時(shí)候,元素被視為可以拖動(dòng)。
拖動(dòng)圖像或者鏈接時(shí),將鼠標(biāo)放在圖像或者鏈接上,按住鼠標(biāo)不放就可以拖動(dòng)它。拖動(dòng)文本時(shí),要先選中文本,然后可以像拖動(dòng)圖像一樣拖動(dòng)選中的文本。
被拖動(dòng)的元素事件
拖動(dòng)圖片時(shí)依次觸發(fā):drapstart,drag,dragend事件。這三個(gè)事件的目標(biāo)都是被拖動(dòng)的元素。
按下鼠標(biāo)鍵并開(kāi)始移動(dòng)鼠標(biāo)時(shí),會(huì)在被拖放元素上觸發(fā)dragstart事件。觸發(fā)dragstart事件后,隨即會(huì)觸發(fā)drag事件,而且在元素被拖動(dòng)期間會(huì)持續(xù)觸發(fā)drag事件;當(dāng)拖動(dòng)停止后,無(wú)論把元素放到了有效的放置目標(biāo)還是無(wú)效的放置目標(biāo)上都會(huì)觸發(fā)dragend事件。
放置目標(biāo)元素事件
當(dāng)某個(gè)元素被拖動(dòng)到一個(gè)有效的放置目標(biāo)上時(shí),會(huì)一次觸發(fā):dragenter,dragover,dragleave或drop事件
只要有元素被拖動(dòng)到放置目標(biāo)上就會(huì)觸發(fā)dragenter事件,緊隨其后的是dragover事件,而且在被拖動(dòng)的元素還在放置目標(biāo)的范圍內(nèi)移動(dòng)時(shí),就會(huì)持續(xù)觸發(fā)dragover事件;如果元素被拖出了放置目標(biāo)就不在觸發(fā)dragover事件,就會(huì)觸發(fā)dragleave事件。如果元素被放到了放置目標(biāo)中,就會(huì)觸發(fā)drop事件而不是dragleave事件。這幾個(gè)事件的目標(biāo)都是作為放置目標(biāo)的元素。
谷歌瀏覽器中支持效果好,火狐效果不好
自定義放置目標(biāo)
我們可以把任何元素變成有效的放置目標(biāo),方法是重寫dragenter和dragover事件的默認(rèn)行為
在FF中,放置事件的默認(rèn)行為是打開(kāi)被放到放置目標(biāo)上的URL。換句話說(shuō),如果是把圖像拖放
到放置目標(biāo)上,頁(yè)面就會(huì)轉(zhuǎn)向圖像文件;如果是把文本拖放到放置目標(biāo)上,則會(huì)導(dǎo)致無(wú)效的URL錯(cuò)誤。
因此,為了讓FF支持正常的拖放,還要取消drop事件的默認(rèn)行為,阻止它打開(kāi)URL。
dataTransfer對(duì)象
原生拖放當(dāng)中最大的特性就是可以利用拖放事件傳遞數(shù)據(jù),這樣使瀏覽器原生就可以支持類似于桌面應(yīng)用的拖放交互功能。要使用數(shù)據(jù)傳輸功能就需要一個(gè)名為 dataTransfer 的接口。
dataTransfer對(duì)象是事件對(duì)象的一個(gè)屬性,它有兩個(gè)主要方法:getData()和setData()。setData() 用于保存值,getData() 用于獲得 setData() 保存的值。
在拖動(dòng)文本框中的文本時(shí),瀏覽器會(huì)調(diào)用setData()方法,將拖動(dòng)的文本以"text"格式保存在dataTransfer對(duì)象中。類似的,在拖放鏈接或者圖像時(shí),會(huì)調(diào)用setData()方法并保存URL。然后,在這些元素被拖放到放置目標(biāo)時(shí),就可以通過(guò)getData()方法讀到這些數(shù)據(jù)了。
保存的數(shù)據(jù)類型為"text"或"url",在HTML5中這兩種數(shù)據(jù)類型被映射為"text/plain"和"text/uri-list"
將數(shù)據(jù)保存為文本和URL是有區(qū)別的。如果將數(shù)據(jù)保存為文本格式,那么數(shù)據(jù)不會(huì)得到任何特殊處理。而如果將數(shù)據(jù)保存為URL,瀏覽器會(huì)將其當(dāng)成網(wǎng)頁(yè)中的鏈接。換句話說(shuō),如果你把它放置到另一個(gè)瀏覽器窗口中,瀏覽器就會(huì)打開(kāi)該URL。
Demo:
文本拖放:
<!DOCTYPE HTML>
<html>
<meta charset="utf-8">
<title>HTML5文本拖放</title>
<head>
<style type="text/css">
#div1 {width:220px;height:185px;padding:10px;border:1px solid #aaaaaa;}
</style>
</head>
<body>
<p id="p1">拖動(dòng)文本到矩形框中:</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<script type="text/javascript">
function allowDrop(ev)
{
ev.preventDefault();
}
function drag(ev)
{
//dataTransfer.setData() 方法設(shè)置被拖數(shù)據(jù)的數(shù)據(jù)類型和值
//這里數(shù)據(jù)類型是 "Text",值是p標(biāo)簽中的文本
ev.dataTransfer.setData("Text",document.getElementById("p1").innerHTML);
}
function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.innerHTML=data;
}
</script>
</body>
</html>
鏈接拖放:
<!DOCTYPE HTML>
<html>
<meta charset="utf-8">
<title>HTML5鏈接拖放</title>
<head>
<style type="text/css">
#div1 {width:220px;height:185px;padding:10px;border:1px solid #aaaaaa;}
</style>
</head>
<body>
<a id="aa">鏈接到百度</a>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<script type="text/javascript">
/*
ondragover 事件規(guī)定在何處放置被拖動(dòng)的數(shù)據(jù)。
默認(rèn)地,無(wú)法將數(shù)據(jù)元素放置到其他元素中。如果需要設(shè)置允許放置,我們必須阻止對(duì)元素的默認(rèn)處理方式。
*/
function allowDrop(ev)
{
ev.preventDefault();
}
function drag(ev)
{
//dataTransfer.setData() 方法設(shè)置被拖數(shù)據(jù)的數(shù)據(jù)類型和值
//這里數(shù)據(jù)類型是 "Text",值是p標(biāo)簽中的文本
ev.dataTransfer.setData("URL",document.getElementById(data).href);
}
function drop(ev)
{
//調(diào)用 preventDefault() 來(lái)避免瀏覽器對(duì)數(shù)據(jù)的默認(rèn)處理(drop 事件的默認(rèn)行為是以鏈接形式打開(kāi))
ev.preventDefault();
//通過(guò) dataTransfer.getData("Text") 方法獲得被拖的數(shù)據(jù)。該方法將返回在 setData() 方法中設(shè)置為相同類型的任何數(shù)據(jù)。
var data=ev.dataTransfer.getData("URL");
ev.target.innerHTML=data;
}
</script>
</body>
</html>
圖片拖放:
<!DOCTYPE HTML>
<html>
<meta charset="utf-8">
<title>HTML5圖片拖放</title>
<head>
<style type="text/css">
#div1 {width:220px;height:185px;padding:10px;border:1px solid #aaaaaa;}
</style>
</head>
<body>
<p id="p1">拖動(dòng)圖片到矩形框中:</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img id="drag1" src="abao.png" draggable="true" ondragstart="drag(event)" width="220" height="181">
<script type="text/javascript">
function allowDrop(ev)
{
ev.preventDefault();
}
function drag(ev)
{
//dataTransfer.setData() 方法設(shè)置被拖數(shù)據(jù)的數(shù)據(jù)類型和值
//這里數(shù)據(jù)類型是 "Text",值是可拖動(dòng)元素的 id ("drag1")
ev.dataTransfer.setData("Text",ev.target.id);
}
function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</body>
</html>
圖片來(lái)回拖放:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>圖片來(lái)回拖放</title>
<style type="text/css">
div{width: 230px;height: 185px;padding: 10px;float: left;margin-right: 10px;border: 1px solid#ccc;}
</style>
</head>
<body>
<div id="box1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="box2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<img src="abao.png" id="drag1" draggable="true" ondragstart="drag(event)">
<script type="text/javascript">
function allowDrop(ev){
ev.preventDefault();
}
function drag(ev){
ev.dataTransfer.setData("Text",ev.target.id);
}
function drop(ev){
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</body>
</html>
dropEffect和effectAllowed屬性
利用dataTransfer對(duì)象,不光是能夠傳輸數(shù)據(jù),還能夠通過(guò)它來(lái)確定被拖動(dòng)的元素以及作為放置目標(biāo)的元素能夠接收什么操作。這需要訪問(wèn)其兩個(gè)屬性:dropEffect屬性和effectAllowed屬性。
dropEffect 瀏覽器會(huì)根據(jù)不同的值顯示不同類型的光標(biāo),提升用戶放置后的行為。 dropEffect 包括以下幾個(gè)值:
•"none": 不能把拖動(dòng)的元素放在這里
•"move": 應(yīng)該把拖動(dòng)的元素移動(dòng)到放置目標(biāo)
•"copy": 應(yīng)該把拖動(dòng)的元素復(fù)制到放置目標(biāo)
•"link":表示放置目標(biāo)會(huì)打開(kāi)拖動(dòng)的元素 (但拖動(dòng)的元素必須是一個(gè)鏈接,有URL)
瀏覽器僅僅會(huì)幫你改變光標(biāo)的類型,但是要實(shí)現(xiàn)怎樣的效果都是要開(kāi)發(fā)者自己去實(shí)現(xiàn)。
dropEffect屬性只有搭配effectAllowed屬性才有用,effectAllowed屬性表示允許拖動(dòng)元素的哪種dropEffect行為,它的值有以下幾種:
•"uninitialized":沒(méi)有給被拖動(dòng)的元素設(shè)置任何放置行為。
•"none": 被拖動(dòng)的元素不能有任何行為
•"copy“:只允許值為 “copy” 的放置行為
•"link":只允許值為 “l(fā)ink” 的放置行為
•"move":只允許值為 “move” 的放置行為
•"copyLink": 允許值為 “copy” 和 “l(fā)ink” 的放置行為
•"copyMove": 允許值為 “copy” 和 “move” 的放置行為
•"linkMove": 允許值為 “l(fā)ink” 和 “move” 的放置行為
•"all": 允許所有放置行為
必須在ondragstart事件處理程序中設(shè)置effectAllowed屬性
Demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My-dropEffect and effectAllowed</title>
</head>
<body>
<a >鏈接到百度</a>
<div style="width: 200px; height: 100px; float: right; background: red" id="droptarget"></div>
<div id="output"></div>
<script type="text/javascript" src="EventUtil.js"></script>
<script type="text/javascript">
var droptarget = document.getElementById("droptarget");//獲取放置目標(biāo)
var link = document.links[0];
//console.log(document.links);//HTMLCollection[a]
//console.log(document.links[0]);// <a >
function handleEvent(event){
document.getElementById("output").innerHTML += event.type + "<br>";
switch(event.type){
case "dragstart":
case "dragend":
event.dataTransfer.dropEffect = "link";//表示放置目標(biāo)會(huì)打開(kāi)拖動(dòng)的元素。要想使用dropEffect,必須進(jìn)行相應(yīng)的設(shè)置,這里將其設(shè)置為link
break;
case "dragenter":
case "dragover":
EventUtil.preventDefault(event);
event.dataTransfer.effectAllowed = "link";//表示值允許"link"的dropEffect
break;
case "drop":
case "dragleave":
droptarget.innerHTML = event.dataTransfer.getData("url") || event.dataTransfer.getData("text/uri-list");
//event.dataTransfer.getData("url") || event.dataTransfer.getData("text/uri-list");是讀取URL
}
}
EventUtil.addHandler(droptarget, "dragenter", handleEvent);
EventUtil.addHandler(droptarget, "dragover", handleEvent);
EventUtil.addHandler(droptarget, "dragleave", handleEvent);
EventUtil.addHandler(droptarget, "drop", handleEvent);
EventUtil.addHandler(link, "dragstart", handleEvent);
EventUtil.addHandler(link, "dragend", handleEvent);
</script>
</body>
</html>
Demo2:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My-dropEffect and effectAllowed</title>
</head>
<body>
<a >鏈接到百度</a>
<p>哈哈哈哈</p>
<div style="width: 200px; height: 100px; float: right; background: red" id="droptarget"></div>
<div id="output"></div>
<script type="text/javascript" src="../EventUtil.js"></script>
<script type="text/javascript">
var droptarget = document.getElementById("droptarget");//獲取放置目標(biāo)
var link = document.links[0];
//console.log(document.links);//HTMLCollection[a]
//console.log(document.links[0]);// <a >
function handleEvent(event){
document.getElementById("output").innerHTML += event.type + "<br>";
switch(event.type){
case "dragstart":
case "dragend":
event.dataTransfer.dropEffect = "move";//表示應(yīng)該把拖動(dòng)的元素移動(dòng)到放置目標(biāo)
case "dragenter":
case "dragover":
EventUtil.preventDefault(event);
event.dataTransfer.effectAllowed = "move";//表示值允許"move"的dropEffect
break;
case "drop":
case "dragleave":
EventUtil.preventDefault(event);
//這里是為了阻止放置事件的默認(rèn)行為:打開(kāi)被放到放置目標(biāo)上的URL
droptarget.innerHTML = event.dataTransfer.getData("Text");
}
}
EventUtil.addHandler(droptarget, "dragenter", handleEvent);
EventUtil.addHandler(droptarget, "dragover", handleEvent);
EventUtil.addHandler(droptarget, "dragleave", handleEvent);
EventUtil.addHandler(droptarget, "drop", handleEvent);
EventUtil.addHandler(link, "dragstart", handleEvent);
EventUtil.addHandler(link, "dragend", handleEvent);
</script>
</body>
</html>
以上這篇淺談js原生拖放就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Vue.js實(shí)現(xiàn)拖放效果的實(shí)例
- 談?wù)剬?duì)JavaScript原生拖放的深入理解
- javascript實(shí)現(xiàn)拖放效果
- JavaScript實(shí)現(xiàn)的多種鼠標(biāo)拖放效果
- JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)對(duì)象拖放功能的方法
- javascript 拖放效果實(shí)現(xiàn)代碼
- JavaScript 拖放效果代碼
- Javascript拖拽&拖放系列文章3之細(xì)說(shuō)事件對(duì)象
- JavaScript 圖片放大鏡(可拖放、縮放效果)
- JS實(shí)現(xiàn)的簡(jiǎn)易拖放效果示例
相關(guān)文章
js實(shí)現(xiàn)HTML中Select二級(jí)聯(lián)動(dòng)的實(shí)例
下面小編就為大家分享一篇js實(shí)現(xiàn)HTML中Select二級(jí)聯(lián)動(dòng)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
three.js設(shè)置物體的縮放和旋轉(zhuǎn)代碼示例
最近在用three.js做三維模型的時(shí)候,需要通過(guò)鼠標(biāo)滑輪向前來(lái)控制視角朝鼠標(biāo)的位置放大,然后通過(guò)鼠標(biāo)滑輪向后將視角復(fù)原,這篇文章主要給大家介紹了關(guān)于three.js如何設(shè)置物體的縮放和旋轉(zhuǎn)的相關(guān)資料,需要的朋友可以參考下2023-11-11
詳解webpack+express多頁(yè)站點(diǎn)開(kāi)發(fā)
這篇文章主要介紹了詳解webpack+express多頁(yè)站點(diǎn)開(kāi)發(fā)2017-12-12
jquery 實(shí)現(xiàn)上下滾動(dòng)效果示例代碼
上下滾動(dòng)的效果,不用說(shuō),大家都有看到過(guò),本文為大家介紹下使用jquery實(shí)現(xiàn)上下滾動(dòng)效果,感興趣的朋友可以參考下,希望對(duì)大家有所幫助2013-08-08
Bootstrap popover 實(shí)現(xiàn)鼠標(biāo)移入移除顯示隱藏功能方法
下面小編就為大家分享一篇Bootstrap popover 實(shí)現(xiàn)鼠標(biāo)移入移除顯示隱藏功能方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
js實(shí)現(xiàn)簡(jiǎn)單的無(wú)縫輪播效果
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)簡(jiǎn)單的無(wú)縫輪播效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-09-09

