摘要:前言拖動(dòng)是添加的提供了元素拖動(dòng)的原生支持拖動(dòng)相對(duì)于其他的事件復(fù)雜了一些原因就在于拖動(dòng)是被拖動(dòng)元素與被放置元素的互動(dòng)涉及到了兩個(gè)元素而不是一個(gè)導(dǎo)致流程的復(fù)雜但是其中的很多設(shè)計(jì)是有規(guī)律可循的現(xiàn)在我們來看一個(gè)基本的使用場(chǎng)景這里有兩個(gè)元素和是可拖動(dòng)
前言
拖動(dòng)api是HTML5添加的API,提供了元素拖動(dòng)的原生支持
拖動(dòng)API相對(duì)于其他的事件API復(fù)雜了一些,原因就在于拖動(dòng)是被拖動(dòng)元素與被放置元素的互動(dòng)涉及到了兩個(gè)元素,而不是一個(gè)導(dǎo)致流程的復(fù)雜,但是其中的很多設(shè)計(jì)是有規(guī)律可循的.
現(xiàn)在我們來看一個(gè)基本的使用場(chǎng)景,這里有兩個(gè)元素A和B,A是可拖動(dòng)元素而B是可放置元素,我們將A放置到B中
鼠標(biāo)按下后拖動(dòng)元素A,觸發(fā)A的dragstart事件
開始移動(dòng)A元素
剛剛觸碰到B容器,觸發(fā)B的dragenter事件
移動(dòng)到B上方
觸發(fā)B容器的dragover事件,該事件類似于mouseover事件是連續(xù)觸發(fā)的
松開鼠標(biāo)放置A
觸發(fā)B容器的drop事件
觸發(fā)A元素的dragend事件
基本流程我們來實(shí)現(xiàn)上面的幾個(gè)步驟
html
目標(biāo)區(qū)域
注意:被拖動(dòng)的元素需要設(shè)置draggable屬性
css
html, body { height: 100%; } html, body, div { margin: 0; padding: 0; box-sizing: border-box; } #test { margin: 0 auto; margin-top: 10%; width: 50%; height: 50%; background: #4CB8C4; background: linear-gradient(to right, #3CD3AD, #4CB8C4); box-shadow: 0 0 15px -3px black; } #display { margin: 0 auto; margin-top: 10%; width: 30%; height: 30%; background-color: rgba(0, 0, 0, 0.055); }
javascript
let dargElem = document.getElementById("test"); let targetElem = document.getElementById("display"); dargElem.addEventListener("dragstart", (event) => { // 被拖動(dòng)元素開始事件 console.log(event); }) // 拖動(dòng)結(jié)束事件 dargElem.addEventListener("dragend", (event) => { console.log("拖動(dòng)結(jié)束事件"); }) // 進(jìn)入容器的事件 targetElem.addEventListener("dragenter", (event) => { event.preventDefault(); console.log("拖動(dòng)進(jìn)入事件"); }) // 懸浮到容器上方的事件 targetElem.addEventListener("dragover", (event) => { event.preventDefault(); }) // 拖動(dòng)事件 targetElem.addEventListener("drop", (event) => { console.log("觸發(fā)放置事件") })
這個(gè)例子中dargElem保存的是被拖動(dòng)元素,我們?yōu)樗?cè)了dragstart和dragend事件,
另外一個(gè)變量targetElem是容器元素我們?yōu)樗?cè)了dragenter dragover drop 事件
控制臺(tái)輸出:
開始拖動(dòng) 拖動(dòng)進(jìn)入事件 觸發(fā)放置事件 拖動(dòng)結(jié)束事件
注意:這個(gè)例子中使用了event.preventDefault()用于阻止默認(rèn)的行為,例如拖動(dòng)a標(biāo)簽的時(shí)候有可能觸發(fā)默認(rèn)的跳轉(zhuǎn)行為
所有事件列表(不包含廠商事件和瀏覽器不支持事件):
被拖動(dòng)的對(duì)象
dragstart 拖動(dòng)開始觸發(fā)
drag 拖動(dòng)過程中觸發(fā) 連續(xù)觸發(fā)
dragend 拖動(dòng)結(jié)束后觸發(fā)
被當(dāng)作容器的元素
dragenter 元素進(jìn)入時(shí)候觸發(fā)
dragover 可拖動(dòng)元素置于容器元素上方時(shí)觸發(fā) 連續(xù)觸發(fā)
drop 可拖動(dòng)元素置入到容器元素中觸發(fā)
dragleave 可拖動(dòng)元素移動(dòng)出容器元素時(shí)候觸發(fā)
注意:容器元素一定需要監(jiān)聽dragover事件并且一開始調(diào)用event.preventDefault()后續(xù)的drop才會(huì)觸發(fā)dragover相當(dāng)于是一個(gè)過濾器,只允許指定的元素可以觸發(fā)drop事件
數(shù)據(jù)的交互前面說道拖動(dòng)事件是兩個(gè)元素的互動(dòng),但是僅僅使用事件是不夠的,我們需要其他的手段在兩個(gè)元素之間傳遞信息
在dragstart事件觸發(fā)的時(shí)候所提供的event對(duì)象中含有一個(gè)DataTransfer對(duì)象,這個(gè)對(duì)象允許在多個(gè)事件中保存信息且在所有拖動(dòng)事件中存在
簡(jiǎn)單信息傳遞操作:
被拖動(dòng)元素調(diào)用該對(duì)象的setData()方法設(shè)置值
容器元素在drop事件中使用event對(duì)象的DataTransfer屬性的getData()方法獲取在dragstart事件中設(shè)置的值
例子:
let dargElem = document.getElementById("test"); let targetElem = document.getElementById("display"); dargElem.addEventListener("dragstart", (event) => { event.dataTransfer.setData("test",[1,2,3]); }) // 必須設(shè)置 targetElem.addEventListener("dragover", (event) => { event.preventDefault(); }) // 拖動(dòng)事件 targetElem.addEventListener("drop", (event) => { event.preventDefault(); console.log(event.dataTransfer.getData("test")); })
可以看到DataTransfer數(shù)據(jù)的設(shè)置就是典型的鍵值操作而已
綜合實(shí)例一個(gè)來自MDN的例子:
html
This div is draggable
css
#draggable { width: 200px; height: 20px; text-align: center; background: white; } .dropzone { width: 200px; height: 20px; background: blueviolet; margin-bottom: 10px; padding: 10px; }
javascript
var dragged; /* 可拖動(dòng)的目標(biāo)元素會(huì)觸發(fā)事件 */ document.addEventListener("drag", function( event ) { }, false); document.addEventListener("dragstart", function( event ) { // 保存拖動(dòng)元素的引用(ref.) dragged = event.target; // 使其半透明 event.target.style.opacity = .5; }, false); document.addEventListener("dragend", function( event ) { // 重置透明度 event.target.style.opacity = ""; }, false); /* 放下目標(biāo)節(jié)點(diǎn)時(shí)觸發(fā)事件 */ document.addEventListener("dragover", function( event ) { // 阻止默認(rèn)動(dòng)作 event.preventDefault(); }, false); document.addEventListener("dragenter", function( event ) { // 當(dāng)可拖動(dòng)的元素進(jìn)入可放置的目標(biāo)高亮目標(biāo)節(jié)點(diǎn) if ( event.target.className == "dropzone" ) { event.target.style.background = "purple"; } }, false); document.addEventListener("dragleave", function( event ) { // 當(dāng)拖動(dòng)元素離開可放置目標(biāo)節(jié)點(diǎn),重置其背景 if ( event.target.className == "dropzone" ) { event.target.style.background = ""; } }, false); document.addEventListener("drop", function( event ) { // 阻止默認(rèn)動(dòng)作(如打開一些元素的鏈接) event.preventDefault(); // 移動(dòng)拖動(dòng)的元素到所選擇的放置目標(biāo)節(jié)點(diǎn) if ( event.target.className == "dropzone" ) { event.target.style.background = ""; dragged.parentNode.removeChild( dragged ); event.target.appendChild( dragged ); } }, false);DataTransfer詳解
DataTransfer不僅僅用于元素之間信息的傳遞,同時(shí)可以控制拖動(dòng)的樣式,以及傳遞額外的信息
屬性:
dropEffect 類型 String
effectAllowed 類型 String
files 類型 FileList
types 類型 DOMStringList
方法:
void addElement(in Element element)
void clearData([in String type])
String getData(in String type)
void setData(in String type, in String data)
void setDragImage(in nsIDOMElement image, in long x, in long y)
這里只講解一下dropEffect和effectAllowed因?yàn)檫@里有坑files屬性用于從瀏覽器外部拖入文件時(shí)候使用types使用較少這里不提了
提供MDN鏈接,看完本文后可以查閱剩下的方法和屬性:
https://developer.mozilla.org...
dropEffect和effectAllowed用于控制拖動(dòng)的時(shí)候光標(biāo)角標(biāo)的樣式,過濾不同的類型拖動(dòng)行為
dropEffect可能的值:
copy: 復(fù)制到新的位置
move: 移動(dòng)到新的位置.
link: 建立一個(gè)源位置到新位置的鏈接.
none: 禁止放置(禁止任何操作).
effectAllowed可能的值:
copy: 復(fù)制到新的位置.
move:移動(dòng)到新的位置 .
link:建立一個(gè)源位置到新位置的鏈接.
copyLink: 允許復(fù)制或者鏈接.
copyMove: 允許復(fù)制或者移動(dòng).
linkMove: 允許鏈接或者移動(dòng).
all: 允許所有的操作.
none: 禁止所有操作.
uninitialized: 缺省值(默認(rèn)值), 相當(dāng)于 all.
簡(jiǎn)單來說在被拖動(dòng)元素的事件中設(shè)置effectAllowed屬性表示期待的拖動(dòng)樣式,而在容器元素中設(shè)置dropEffect表示容器指定的樣式,其他的設(shè)置都會(huì)被忽視
對(duì)于dropEffect只有在dragover事件中中修改值才會(huì)影響樣式,我用的是Chrome66
對(duì)于effectAllowed只有在dragstart事件中有效
例子雙方都使用link樣式:
let dargElem = document.getElementById("test"); let targetElem = document.getElementById("display"); // 拖動(dòng)開始事件 dargElem.addEventListener("dragstart", (event) => { event.dataTransfer.effectAllowed = "link"; }) // 懸浮到容器上方的事件 targetElem.addEventListener("dragover", (event) => { event.dataTransfer.dropEffect = "link"; event.preventDefault(); }) // 拖動(dòng)事件 targetElem.addEventListener("drop", (event) => { console.log("pass") event.preventDefault(); })
這個(gè)例子中drop事件被觸發(fā)
例子effectAllowed設(shè)置為copy而dropEffect設(shè)置為link:
let dargElem = document.getElementById("test"); let targetElem = document.getElementById("display"); // 拖動(dòng)開始事件 dargElem.addEventListener("dragstart", (event) => { event.dataTransfer.effectAllowed = "link"; }) // 懸浮到容器上方的事件 targetElem.addEventListener("dragover", (event) => { event.dataTransfer.dropEffect = "link"; event.preventDefault(); }) // 拖動(dòng)事件 targetElem.addEventListener("drop", (event) => { console.log("pass") event.preventDefault(); })
這個(gè)例子執(zhí)行的結(jié)果就是拖動(dòng)時(shí)候的角標(biāo)一直是禁止符號(hào),在容器元素上松開也不會(huì)觸發(fā)drop事件
參考鏈接https://developer.mozilla.org...https://developer.mozilla.org...
https://blog.csdn.net/baidu_3...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/96738.html
摘要:回調(diào)函數(shù)回調(diào)函數(shù)文件夾拖動(dòng)攔截默認(rèn)行為,并阻止冒泡文件夾拖動(dòng)或者文件拖動(dòng),瀏覽器默認(rèn)會(huì)直接打開顯示,圖片尤為明顯,所以首先需要阻止默認(rèn)行為。 前言 文件拖動(dòng)上傳,對(duì)于個(gè)別應(yīng)用場(chǎng)景十分有效,實(shí)現(xiàn)起來也并不難。參見 瀏覽器圖片預(yù)覽 --http://blog.segmentfault.com/bornkiller/1190000000428572。 現(xiàn)在更進(jìn)一步,做到文件夾拖動(dòng)。Fils...
摘要:該區(qū)域代表可以被所控制的畫布。那么現(xiàn)在第二個(gè)問題,識(shí)別該文檔,這或許不是大部分用戶的需求,但小部分用戶并不意味著人數(shù)少。因此一個(gè)基于的請(qǐng)求于標(biāo)準(zhǔn)內(nèi)提出。 前言 作為程序員,技術(shù)的落實(shí)與鞏固是必要的,因此想到寫個(gè)系列,名為 why what or how 每篇文章試圖解釋清楚一個(gè)問題。 這次的 why what or how 主題:現(xiàn)在幾乎所有人都知道了 HTML5 ,那么 H5 到底相...
閱讀 2924·2019-08-30 15:55
閱讀 2917·2019-08-30 15:53
閱讀 2365·2019-08-26 13:47
閱讀 2644·2019-08-26 13:43
閱讀 3231·2019-08-26 13:33
閱讀 2873·2019-08-26 11:53
閱讀 1850·2019-08-23 18:35
閱讀 872·2019-08-23 17:16