关于怎么在手机端实现一个拖拽的操作
手機(jī)端,肯定是監(jiān)聽(tīng)touchstart,touchmove,touchend事件 先來(lái)看看效果
當(dāng)拖拽時(shí),拖拽到哪個(gè)節(jié)點(diǎn)下面,就把哪個(gè)節(jié)點(diǎn)添加到這個(gè)下面
<div>1111</div><div>2222</div><div>3333</div><div>4444</div><div>5555</div><div class="hightlight"></div>前面的div,是我們要拖拽的對(duì)象,highlight是用來(lái)高亮當(dāng)前拖到了哪個(gè)下面,以便于用戶體驗(yàn) ###1.初始化
// 獲取所有的節(jié)點(diǎn)var divList = Array.from(document.querySelectorAll('div'))// 用來(lái)高亮的節(jié)點(diǎn)var hightlight = document.querySelector('.hightlight')// 手指一開(kāi)始命中的那個(gè)節(jié)點(diǎn)var lastChild = null// 來(lái)自于lastChild,在手指離開(kāi)之前,都是克隆的var currentChild = null// 要添加到的那個(gè)父節(jié)點(diǎn)var needAppendParent = null// 用來(lái)初始化每一個(gè)節(jié)點(diǎn)的邊距,不要每次去算,觸發(fā)回流function init() {divList.forEach(item => {var bound = item.getBoundingClientRect()item.bound = JSON.parse(JSON.stringify(bound))})}init()初始化,就是把每一個(gè)拖拽的對(duì)象的邊距值全部保存起來(lái),避免每次去計(jì)算導(dǎo)致的重繪
1.touchstart
/*手指移上去時(shí),克隆命中的這個(gè)節(jié)點(diǎn),并且這是它當(dāng)前的位置,為手指移上去的位置,顯示當(dāng)前的hightlight命中了哪個(gè)*/document.body.addEventListener('touchstart', function(e) {lastChild = e.targetcurrentChild = 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;`})手指移上去時(shí),我們就記下當(dāng)前命中的這個(gè)節(jié)點(diǎn),并且克隆出一個(gè)節(jié)點(diǎn)來(lái),它設(shè)置絕對(duì)定位,位置根據(jù)手指的位置變動(dòng),并且設(shè)置高亮顯示,高亮當(dāng)前命中的這個(gè)節(jié)點(diǎn),hightlight的位置信息,寬高,都是有命中的那個(gè)節(jié)點(diǎn)算出
2.touchmove
/*讓這個(gè)節(jié)點(diǎn)一直跟著手指動(dòng),并且去判斷當(dāng)前高亮哪個(gè)節(jié)點(diǎn),并且記下這個(gè)節(jié)點(diǎn)*/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時(shí)做了兩件事情,第一件是,讓克隆的那個(gè)節(jié)點(diǎn)跟著手指走,第二件判斷當(dāng)前節(jié)點(diǎn)的左上角,是否在某個(gè)節(jié)點(diǎn)里面,即是否大于某個(gè)節(jié)點(diǎn)的左上角,小于某個(gè)節(jié)點(diǎn)的右下角,如果是,記住當(dāng)前節(jié)點(diǎn),并且高亮它
3.touchend
/*刪除手動(dòng)加的樣式,移除上一個(gè)節(jié)點(diǎn),把克隆的節(jié)點(diǎn)添加到高亮的那個(gè)節(jié)點(diǎn)里面,hightlight隱藏*/document.body.addEventListener('touchend', function(e) {currentChild.style.cssText = ''needAppendParent.appendChild(currentChild)document.body.removeChild(lastChild)hightlight.style.cssText = `display:none;`})touchend,即手指放開(kāi)時(shí),要做的事情,去除當(dāng)前節(jié)點(diǎn)的position樣式,并且把這個(gè)克隆的節(jié)點(diǎn)加到高亮的那個(gè)節(jié)點(diǎn)里面去,再移除掉那個(gè)被克隆的節(jié)點(diǎn),高亮框隱藏 假如我們要實(shí)現(xiàn)添加到高亮的那個(gè)節(jié)點(diǎn)后面,可以使用insertAdjacentElement來(lái)實(shí)現(xiàn),具體看代碼
/*刪除手動(dòng)加的樣式,移除上一個(gè)節(jié)點(diǎn),把克隆的節(jié)點(diǎn)添加到高亮的那個(gè)節(jié)點(diǎn)里面,hightlight隱藏*/document.body.addEventListener('touchend', function(e) {currentChild.style.cssText = ''needAppendParent.insertAdjacentElement('afterend', currentChild)document.body.removeChild(lastChild)hightlight.style.cssText = `display:none;`})效果
注:本demo僅僅是講解實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的拖拽功能,很多場(chǎng)景沒(méi)考慮,勿噴更多專業(yè)前端知識(shí),請(qǐng)上 【猿2048】www.mk2048.com
總結(jié)
以上是生活随笔為你收集整理的关于怎么在手机端实现一个拖拽的操作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [译] Airbnb 在 React N
- 下一篇: 为什么你应该尝试@reach/route