手機端,確定是監聽touchstart,touchmove,touchend事件 先來看看效果 css
當拖拽時,拖拽到哪一個節點下面,就把哪一個節點添加到這個下面bash
<div>1111</div>
<div>2222</div>
<div>3333</div>
<div>4444</div>
<div>5555</div>
<div class="hightlight"></div>
複製代碼
前面的div,是咱們要拖拽的對象,highlight是用來高亮當前拖到了哪一個下面,以便於用戶體驗 ###1.初始化app
// 獲取全部的節點
var divList = Array.from(document.querySelectorAll('div'))
// 用來高亮的節點
var hightlight = document.querySelector('.hightlight')
// 手指一開始命中的那個節點
var lastChild = null
// 來自於lastChild,在手指離開以前,都是克隆的
var currentChild = null
// 要添加到的那個父節點
var needAppendParent = null
// 用來初始化每個節點的邊距,不要每次去算,觸發迴流
function init() {
divList.forEach(item => {
var bound = item.getBoundingClientRect()
item.bound = JSON.parse(JSON.stringify(bound))
})
}
init()
複製代碼
初始化,就是把每個拖拽的對象的邊距值所有保存起來,避免每次去計算致使的重繪spa
/*
手指移上去時,克隆命中的這個節點,而且這是它當前的位置,
爲手指移上去的位置,
顯示當前的hightlight命中了哪一個
*/
document.body.addEventListener('touchstart', function(e) {
lastChild = e.target
currentChild = e.target.cloneNode(true)
currentChild.style.cssText = `position:absolute;left:${e.targetTouches[0].pageX }px;top:${e.targetTouches[0].pageY}px;`
document.body.appendChild(currentChild)
hightlight.style.cssText = `display:block;left:${lastChild.bound.left}px;top:${lastChild.bound.top}px;width:${lastChild.bound.width}px;height:${lastChild.bound.height}px;`
})
複製代碼
手指移上去時,咱們就記下當前命中的這個節點,而且克隆出一個節點來,它設置絕對定位,位置根據手指的位置變更,而且設置高亮顯示,高亮當前命中的這個節點,hightlight的位置信息,寬高,都是有命中的那個節點算出code
/*
讓這個節點一直跟着手指動,而且去判斷當前高亮哪一個節點,而且記下這個節點
*/
document.body.addEventListener('touchmove', function(e) {
var currentBound = currentChild.getBoundingClientRect()
currentChild.style.cssText = `position:absolute;left:${e.targetTouches[0].pageX}px;top:${e.targetTouches[0].pageY}px;`
divList.forEach(item => {
if (currentBound.left > item.bound.left && currentBound.left < item.bound.right && currentBound.top > item.bound.top && currentBound.top < item.bound.bottom) {
hightlight.style.cssText = `display:block;left:${item.bound.left}px;top:${item.bound.top}px;width:${lastChild.bound.width}px;height:${lastChild.bound.height}px;`
needAppendParent = item
}
})
})
複製代碼
move時作了兩件事情,第一件是,讓克隆的那個節點跟着手指走,第二件判斷當前節點的左上角,是否在某個節點裏面,便是否大於某個節點的左上角,小於某個節點的右下角,若是是,記住當前節點,而且高亮它cdn
/*
刪除手動加的樣式,移除上一個節點,把克隆的節點添加到高亮的那個節點裏面,hightlight隱藏
*/
document.body.addEventListener('touchend', function(e) {
currentChild.style.cssText = ''
needAppendParent.appendChild(currentChild)
document.body.removeChild(lastChild)
hightlight.style.cssText = `display:none;`
})
複製代碼
touchend,即手指放開時,要作的事情,去除當前節點的position樣式,而且把這個克隆的節點加到高亮的那個節點裏面去,再移除掉那個被克隆的節點,高亮框隱藏 假如咱們要實現添加到高亮的那個節點後面,能夠使用insertAdjacentElement來實現,具體看代碼對象
/*
刪除手動加的樣式,移除上一個節點,把克隆的節點添加到高亮的那個節點裏面,hightlight隱藏
*/
document.body.addEventListener('touchend', function(e) {
currentChild.style.cssText = ''
needAppendParent.insertAdjacentElement('afterend', currentChild)
document.body.removeChild(lastChild)
hightlight.style.cssText = `display:none;`
})
複製代碼
效果 blog
注:本demo僅僅是講解實現一個最簡單的拖拽功能,不少場景沒考慮,勿噴