項目地址👉👉點擊進入,能夠直接設置爲瀏覽器主頁或者桌面快捷方式進行使用,本人在用,長期維護。javascript
徹底開源,你們能夠隨意研究,二次開發。固然仍是十分歡迎你們點個Star⭐⭐⭐
👉👉源碼連接(gitee) 👉👉源碼連接(github)vue
上面是我一個開源的用來收藏網站的小項目,可是現階段只能一個一個的按順序添加網址,這樣就產生了一個問題,那就是後添加的必定在下面,而我若是新添加了一個比較經常使用的網站,而列表又過長的話,每次進入都須要翻到下面去找,實在是太不方便。java
因此我就想添加一個拖拽排序的功能,在編輯模式下,能夠經過拖拽圖標進行排序,退出編輯模式自動保存,這樣就解決了上面的問題,優化了用戶體驗。react
下面就詳細記錄一下此功能的實現。git
首先仍是先學習一下APIgithub
HTML 拖放(Drag and Drop)
接口使應用程序可以在瀏覽器中使用拖放功能。例如,用戶可以使用鼠標選擇可拖拽(draggable)
元素,將元素拖拽到可放置(droppable)
元素,並釋放鼠標按鈕以放置這些元素。拖拽操做期間,會有一個可拖拽元素的半透明快照跟隨着鼠標指針。數組
可用的拖拽事件一共有七個,其中三個是用於拖拽元素的瀏覽器
四個是用於釋放區域的服務器
draggable
屬性並添加 dragstart
事件處理函數id
drop
和 dragover
事件處理函數,並阻止默認事件dragend
事件處理函數<body>
<div class="box" id='box1'> <div id="child" draggable="true"></div> </div>
<div class="box" id='box2'> </div>
</body>
<script> ((doc) => { const box1 = doc.querySelector("#box1") const box2 = doc.querySelector("#box2") const child = doc.querySelector("#child") // 綁定事件函數 const bindEvents = () => { child.addEventListener("drag", handleDrag) child.addEventListener("dragstart", handleDragstart) child.addEventListener("dragend", handleDragend) box2.addEventListener("dragenter", handleDragenter) box2.addEventListener("dragover", handleDragover) box2.addEventListener("dragleave", handleDragleave) box2.addEventListener("drop", handleDrop) }; // 在元素被拖動時觸發 const handleDrag = (ev) => { console.log('🚀🚀 ~ drag 觸發啦'); } // 在元素開始被拖動時觸發 const handleDragstart = (ev) => { console.log('🚀🚀 ~ dragstart 觸發啦'); ev.dataTransfer.setData('id', ev.target.id); } // 在拖動操做完成時觸發 const handleDragend = (ev) => { console.log('🚀🚀 ~ dragend 觸發啦'); } // 當被拖動元素進入到釋放區所佔據的屏幕空間時觸發 const handleDragenter = (ev) => { console.log('🚀🚀 ~ dragenter 觸發啦'); } // 當被拖動元素在釋放區內移動時觸發 const handleDragover = (ev) => { ev.preventDefault(); console.log('🚀🚀 ~ dragover 觸發啦'); } // 當被拖動元素沒有放下就離開釋放區時觸發 const handleDragleave = (ev) => { console.log('🚀🚀 ~ dragleave 觸發啦'); } // 當被拖動元素在釋放區裏放下時觸發 const handleDrop = (ev) => { console.log('🚀🚀 ~ drop 觸發啦'); ev.preventDefault(); const data = ev.dataTransfer.getData("id"); ev.target.appendChild(document.getElementById(data)); } // 初始化函數 const init = () => { bindEvents(); }; // 執行初始化函數 init(); })(document); </script>
複製代碼
原生js
實現拖拽排序我尚未弄,可是在vue
中就很是的簡單,由於咱們在觸發任何事件的時候,均可以拿到元素的index
,咱們能夠靠index
輕易實現。markdown
dragstart
中記錄下舊的索引dragover
中記錄下新的索引,每次通過一個都會更新drop
事件中處理數組,刪掉舊的元素,在目標索引添加新的元素//簡略後的僞代碼 詳情請查看源碼
<div draggable="true" v-for='(item,index) in markList' :key='index'
@dragstart="handleDragstart(index)"
@drop.prevent="handleDrop()"
@dragover.prevent="handleDragover(index)">
</div>
//js
const state = reactive<MarkState>({
// 當前正在拖拽的元素索引
oldItemIndex: -1,
// 將插入的目標位置索引
newItemIndex: -1,
});
// 開始拖拽時觸發
const handleDragstart = (index: number) => {
state.oldItemIndex = index;
};
// 中止拖拽時觸發
const handleDrop = () => {
// 若是位置沒有發生改變 什麼也不作
if (state.newItemIndex === state.oldItemIndex) {
return;
}
// 若是位置發生了改變
emit('change-mark-index', state.oldItemIndex, state.newItemIndex);
};
// 拖拽通過其餘元素時觸發
const handleDragover = (index: number) => {
state.newItemIndex = index;
};
//change-mark-index
// 修改書籤索引
const changeMarkIndex = (oldItemIndex: number, newItemIndex: number) => {
// 刪除老的
const changeItem = marks.value.splice(oldItemIndex, 1)[0];
// 在列表中目標位置增長新的
marks.value.splice(newItemIndex, 0, changeItem);
};
複製代碼
💡拖拽到目標位置後會有位置提示
💡支持拖拽到其餘標籤下
💡添加拖拽動畫
拖拽動畫這裏我試了vue
內部的 transition-group
可是沒有成功,若是你們有什麼思路或者建議,請你們不吝賜教,在下方評論或者私信我,十分感謝🙏🙏🙏.
最後感謝各位的耐心觀看,既然都到這了,點個 👍贊再走吧
🔊項目預覽地址(GitHub Pages):👉👉alanhzw.github.io
🔊項目預覽備用地址(本身的服務器):👉👉warbler.duwanyu.com
🔊源碼地址(gitee):👉👉gitee.com/hzw_0174/wa…
🔊源碼地址(github):👉👉github.com/alanhzw/War…
🔊個人博客:👉👉www.duwanyu.com