使用JavaScript輕松實(shí)現(xiàn)拖拽功能
效果展示
實(shí)現(xiàn)
要實(shí)現(xiàn)該效果需要運(yùn)用 HTML5 的 dragstart 拖放操作事件
通過(guò)去開(kāi)啟dragstart監(jiān)聽(tīng)拖放操作事件就能實(shí)現(xiàn)圖片的拖動(dòng)
<div class="empty"> <div class="fill" draggable="true"></div> </div>
本例子中我們對(duì)fill盒子開(kāi)啟了draggable事件,fill盒子是用來(lái)存照片的
但是這樣并不能形成一個(gè)反饋,只有單純的拖動(dòng)效果,效果如下圖所示
如果想要實(shí)現(xiàn)在拖動(dòng)了圖片后有一個(gè)反饋效果,我們就需要使用JavaScript去監(jiān)聽(tīng)draggable的開(kāi)始拖動(dòng)和結(jié)束拖動(dòng)事件
.hold { border: 5px solid #00ff00; }
const fill = document.querySelector(".fill"); // 拖拽開(kāi)始事件 fill.addEventListener("dragstart", DragStart); function DragStart(e) { this.classList.add("hold"); } // 拖拽結(jié)束事件 fill.addEventListener("dragend", DragEnd); function DragEnd(e) { this.classList.remove("hold"); }
通過(guò)在拖動(dòng)時(shí)給他添加邊框,結(jié)束時(shí)取消以實(shí)現(xiàn)一個(gè)反饋的效果
最后去監(jiān)聽(tīng)empty盒子的即可根據(jù)不同事件觸發(fā)時(shí),實(shí)現(xiàn)不同的效果
const empty = document.querySelectorAll(".empty"); empty.forEach((item) => { // 經(jīng)過(guò)事件 item.addEventListener("dragover", DragOver); // 進(jìn)入事件 item.addEventListener("dragenter", DragEnter); // 離開(kāi)事件 item.addEventListener("dragleave", DragLeave); // 拖拽結(jié)束事件 item.addEventListener("drop", Drop); })
首先通過(guò)類(lèi)名獲取所有的 .empty
元素
然后對(duì)每個(gè)獲取到的元素分別添加了一系列的事件監(jiān)聽(tīng):
item.addEventListener("dragover", DragOver);
:當(dāng)元素上發(fā)生拖曳經(jīng)過(guò)事件時(shí),執(zhí)行DragOver
函數(shù)。item.addEventListener("dragenter", DragEnter);
:當(dāng)元素上發(fā)生拖曳進(jìn)入事件時(shí),執(zhí)行DragEnter
函數(shù)。item.addEventListener("dragleave", DragLeave);
:當(dāng)元素上發(fā)生拖曳離開(kāi)事件時(shí),執(zhí)行DragLeave
函數(shù)。item.addEventListener("drop", Drop);
:當(dāng)元素上發(fā)生拖曳放下事件時(shí),執(zhí)行Drop
函數(shù)。
具體思路就是在拖曳進(jìn)入時(shí)給一個(gè)反饋,當(dāng)拖曳放下時(shí)將元素放入
// 拖拽經(jīng)過(guò)事件 function DragOver(e) { // 阻止默認(rèn)事件 e.preventDefault(); console.log("拖拽經(jīng)過(guò)"); } // 拖拽進(jìn)入事件 function DragEnter(e) { console.log("拖拽進(jìn)入"); this.classList.add("hovered"); } // 拖拽離開(kāi)事件 function DragLeave(e) { console.log("拖拽離開(kāi)"); this.classList.remove("hovered"); } // 拖拽結(jié)束事件 function Drop(e) { console.log("拖拽結(jié)束"); this.className = "empty"; this.append(fill); }
DragOver
函數(shù):- 通過(guò)
e.preventDefault()
阻止了默認(rèn)行為,以確保拖放操作按照預(yù)期進(jìn)行
- 通過(guò)
DragEnter
函數(shù):- 通過(guò)
this.classList.add("hovered")
為當(dāng)前元素添加了一個(gè)名為“hovered”的類(lèi),用于進(jìn)行反饋
- 通過(guò)
DragLeave
函數(shù):- 通過(guò)
this.classList.remove("hovered")
移除了之前添加的“hovered”類(lèi)。
- 通過(guò)
Drop
函數(shù):- 通過(guò)
this.className = "empty"
將當(dāng)前元素的類(lèi)名重置為“empty”,接著通過(guò)this.append(fill)
將fill
元素添加到當(dāng)前元素中
- 通過(guò)
最終就能實(shí)現(xiàn)效果了
完整代碼
<!-- html5特征:<!DOCTYPE html> --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>拖拽效果</title> <style> body { display: flex; justify-content: center; align-items: center; height: 100vh; } .empty { width: 150px; height: 150px; border: 3px solid #ffcccc; margin-left: 10px; background: #dafada; position: relative; } .fill { width: 140px; height: 140px; cursor: pointer; background-image: url(./image.png); background-size: cover; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .hold { border: 5px solid #00ff00; } .hovered{ border: 3px solid #ff0000; } </style> </head> <body> <div class="empty"> <div class="fill" draggable="true"></div> </div> <div class="empty"></div> <div class="empty"></div> <div class="empty"></div> <div class="empty"></div> <script> const fill = document.querySelector(".fill"); // 拖拽開(kāi)始事件 fill.addEventListener("dragstart", DragStart); function DragStart(e) { this.classList.add("hold"); } // 拖拽結(jié)束事件 fill.addEventListener("dragend", DragEnd); function DragEnd(e) { this.classList.remove("hold"); } const empty = document.querySelectorAll(".empty"); empty.forEach((item) => { // 經(jīng)過(guò)事件 item.addEventListener("dragover", DragOver); // 進(jìn)入事件 item.addEventListener("dragenter", DragEnter); // 離開(kāi)事件 item.addEventListener("dragleave", DragLeave); // 拖拽結(jié)束事件 item.addEventListener("drop", Drop); }) // 拖拽經(jīng)過(guò)事件 function DragOver(e) { // 阻止默認(rèn)事件 e.preventDefault(); console.log("拖拽經(jīng)過(guò)"); } // 拖拽進(jìn)入事件 function DragEnter(e) { console.log("拖拽進(jìn)入"); this.classList.add("hovered"); } // 拖拽離開(kāi)事件 function DragLeave(e) { console.log("拖拽離開(kāi)"); this.classList.remove("hovered"); } // 拖拽結(jié)束事件 function Drop(e) { console.log("拖拽結(jié)束"); this.className = "empty"; this.append(fill); } </script> </body> </html>
到此這篇關(guān)于使用JavaScript輕松實(shí)現(xiàn)拖拽功能的文章就介紹到這了,更多相關(guān)JavaScript拖拽功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue elementUi+sortable.js實(shí)現(xiàn)嵌套表格拖拽問(wèn)題
- 淺析原生JavaScript中拖拽屬性draggable的使用
- JavaScript實(shí)現(xiàn)文件的拖拽上傳功能
- vue結(jié)合el-table實(shí)現(xiàn)表格行拖拽排序(基于sortablejs)
- element-plus結(jié)合sortablejs實(shí)現(xiàn)table行拖拽效果
- 手把手教你用Javascript實(shí)現(xiàn)觀察者模式
- js觀察者模式的介紹及使用
- js觀察者模式的彈幕案例
- JavaScript設(shè)計(jì)模式之觀察者模式與發(fā)布訂閱模式詳解
- javascript設(shè)計(jì)模式 – 觀察者模式原理與用法實(shí)例分析
- JavaScript 拖拽與觀察者模式的實(shí)現(xiàn)及應(yīng)用小結(jié)
相關(guān)文章
淺談javascript的Array.prototype.slice.call
發(fā)現(xiàn)大多人都用了Array.prototype.slice.call(argments,0),一直不明白這句是干什么的。而昨天溫習(xí)了slice()方法,再參考Function.call(thisArg[, arg1[, arg2[, ...]]]),還是不得而知(我腦筋轉(zhuǎn)得慢:|)。2015-08-08Google的跟蹤代碼 動(dòng)態(tài)加載js代碼方法應(yīng)用
Google的跟蹤代碼 動(dòng)態(tài)加載js代碼,需要的朋友可以參考下2012-11-11javascript打印html內(nèi)容功能的方法示例
這篇文章主要介紹了javascript打印html內(nèi)容的小示例,大家參考使用2013-11-11前端實(shí)現(xiàn)讀取word文件并將其原樣式展示的幾種方案
在前端直接讀取并原樣展示W(wǎng)ord文檔是一個(gè)相對(duì)復(fù)雜的任務(wù),因?yàn)閃ord文檔的格式(如.doc或.docx)與Web技術(shù)棧使用的格式(HTML、CSS)不兼容,這篇文章主要給大家介紹了關(guān)于前端實(shí)現(xiàn)讀取word文件并將其原樣式展示的幾種方案,需要的朋友可以參考下2024-08-08解決layui使用layui-icon出現(xiàn)默認(rèn)圖標(biāo)的問(wèn)題
今天小編就為大家分享一篇解決layui使用layui-icon出現(xiàn)默認(rèn)圖標(biāo)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-09-09javascript?ES6中set集合、map集合使用方法詳解與源碼實(shí)例
這篇文章主要介紹了javascript?ES6中set、map使用方法詳解與源碼實(shí)例,需要的朋友可以參考下2022-12-12