国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術(shù)文章
文章詳情頁

移動(dòng)端JS實(shí)現(xiàn)拖拽兩種方法解析

瀏覽:69日期:2024-04-17 11:21:44

移動(dòng)端的項(xiàng)目經(jīng)常會(huì)引入手勢(shì)庫(kù)來實(shí)現(xiàn)拖拽

不過如果只是一兩個(gè)頁面用到拖拽,再引入一個(gè)手勢(shì)庫(kù)就很不劃算

最近的項(xiàng)目中就有這么一個(gè)需求:

移動(dòng)端JS實(shí)現(xiàn)拖拽兩種方法解析

因?yàn)榫瓦@一個(gè)地方需要拖拽,所以我就沒有引入第三方庫(kù)

移動(dòng)端的拖拽有兩種主流的實(shí)現(xiàn)方案:

1. 將元素設(shè)置為固定定位,然后在拖拽的時(shí)候修改其定位,實(shí)現(xiàn)拖拽的效果;

2. 使用 transform 中的平移translate 屬性實(shí)現(xiàn)拖拽。

方案一:固定定位 fixed

這種方案的核心就是給元素添加固定定位position:fixed;

但定位之后,元素會(huì)脫離文檔流,會(huì)影響原有但布局

因此在開始拖拽 (觸發(fā)touchstart事件) 的時(shí)候,需要將原本的元素 A 拷貝一份 (cloneNode())

給新元素 A2 添加定位,同時(shí)給原本的元素 A 設(shè)置visibility:hidden; 使之隱藏并占位

1.1 創(chuàng)建遮罩

首先封裝一個(gè)創(chuàng)建遮罩的方法,用于放置拷貝出來的元素,并防止誤觸

createModal (id) { let modal = document.getElementById(id) if (!modal) { // 在沒有遮罩的時(shí)候創(chuàng)建遮罩 modal = document.createElement(’div’) modal.id = id modal.style.cssText = `position: fixed; left: 0; top: 0; right: 0; bottom: 0; z-index: 999;` document.body.appendChild(modal) }},

1.2 開始拖拽

在觸發(fā)touchstart事件的時(shí)候,首先創(chuàng)建遮罩

并通過getBoundingClientRect()方法獲取到元素 A 的坐標(biāo),記錄起點(diǎn)信息

為了記錄起點(diǎn)信息,需要 data 中創(chuàng)建一個(gè)對(duì)象source,用于記錄點(diǎn)擊的位置 client,和初始定位坐標(biāo) start

handleTouchstart (e) { // 開始拖拽 // 創(chuàng)建遮罩層 this.createModal(this.modalID) // modalID 遮罩層的id,由外部定義 let element = e.targetTouches[0] let target = e.target.cloneNode(true) // 拷貝目標(biāo)元素 target.id = this.copyID // copyID 拷貝元素的id,由外部定義 // 記錄初始點(diǎn)擊位置 client,用于計(jì)算移動(dòng)距離 this.source.client = { x: element.clientX, y: element.clientY } // 算出目標(biāo)元素的固定位置 let disX = this.source.start.left = element.target.getBoundingClientRect().left let disY = this.source.start.top = element.target.getBoundingClientRect().top target.style.cssText = `position: fixed; left: ${disX}px; top: ${disY}px;` // 將拷貝的元素放到遮罩中 document.getElementById(this.modalID).appendChild(target)},

1.3 處理拖拽

拖拽的時(shí)候,監(jiān)聽touchmove事件

用【當(dāng)前鼠標(biāo)點(diǎn)位置】減去【初始點(diǎn)擊位置】得到移動(dòng)的距離

再結(jié)合初始坐標(biāo)信息,更新拖拽元素的坐標(biāo)

handleTouchmove (e) { // 拖拽中 let element = e.targetTouches[0] let target = document.getElementById(this.copyID) // 根據(jù)初始點(diǎn)擊位置 client 計(jì)算移動(dòng)距離 let left = this.source.start.left + element.clientX - this.source.client.x let top = this.source.start.top + element.clientY - this.source.client.y // 移動(dòng)當(dāng)前元素 target.style.left = `${left}px` target.style.top = `${top}px`},

1.4 拖拽結(jié)束

拖拽結(jié)束的時(shí)候,記錄終點(diǎn)位置,刪除遮罩

handleTouchend (e) { // 拖拽結(jié)束 let end = { x: e.changedTouches[0].clientX, y: e.changedTouches[0].clientY } // 刪除遮罩層 let modal = document.getElementById(this.modalID) document.body.removeChild(modal) // 處理結(jié)果 this.doingSth(end)},

不過上面的代碼只實(shí)現(xiàn)了拖拽的功能,并沒有對(duì)目標(biāo)元素 A 進(jìn)行顯示/隱藏的操作

可以根據(jù)業(yè)務(wù)場(chǎng)景自行添加,或者參考方案二

方案二:平移動(dòng)畫translate

這種方案更為簡(jiǎn)單,不需要?jiǎng)?chuàng)建額外的 DOM 元素

只需對(duì)原本的元素添加 transform 屬性,甚至不需要 transition 屬性

然后在拖拽過程中,實(shí)時(shí)更新transform: translate(X, Y)中 x, y 的坐標(biāo)信息,實(shí)現(xiàn)拖拽

2.1 開始拖拽

開始拖拽的時(shí)候,只需要記錄起點(diǎn)坐標(biāo)

handleTouchstart (e) { // 開始拖拽 let element = e.targetTouches[0]// 記錄初始 client 位置,用于計(jì)算移動(dòng)距離 this.source.client = { x: element.clientX, y: element.clientY }},

為了防止拖拽的過程中誤觸,建議使用方案一的createModal()方法創(chuàng)建一個(gè)遮罩

2.2 處理拖拽

根據(jù)當(dāng)前坐標(biāo)和起點(diǎn)坐標(biāo),計(jì)算出距離,然后更新 translate 的坐標(biāo)

handleTouchmove (e) { // 拖拽中 let element = e.targetTouches[0] // 根據(jù)初始 client 位置計(jì)算移動(dòng)距離 let x = element.clientX - this.source.client.x let y = element.clientY - this.source.client.y // 移動(dòng)當(dāng)前元素 element.target.style.cssText = `transform: translate(${x}px, ${y}px);`},

2.3 拖拽結(jié)束

拖拽完成后,清除平移動(dòng)畫

handleTouchend (e) { // 拖拽結(jié)束 // 清除拖拽樣式 e.target.style.cssText = `transform: none;`},

小結(jié):

方案一在獲取目標(biāo)元素的坐標(biāo)信息的時(shí)候使用了 getBoundingClientRect() 方法

但這個(gè)方法性能不高,應(yīng)當(dāng)少用

而且即時(shí)使用了該方法,最后得到的 left 和 top 也不夠精確,touchstart 的時(shí)候,元素有明顯的閃動(dòng)

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 精品国产a | 久久精品亚洲精品国产欧美 | 亚州不卡| 国产一区二区精品久久凹凸 | 最新理论三级中文在线观看 | 国产欧美综合一区二区 | 欧美成人免费一级人片 | 亚洲第一视频在线播放 | 91久久色 | 欧美精品黄页免费高清在线 | 成人在线免费观看网站 | 在线视频免费观看a毛片 | 综合久久一区二区三区 | 亚洲精品国产精品国自产观看 | 精品日韩二区三区精品视频 | 成人男女视频 | 日韩在线播放中文字幕 | 精品国产免费人成在线观看 | 国产成年人视频 | 国产精成人品 | 国产丶欧美丶日韩丶不卡影视 | 久久99久久 | 三级毛片在线免费观看 | 全部孕妇毛片 | 一区二区三区视频网站 | 国内精品久久久久久久久久影视 | 欧美激情国产一区在线不卡 | 久久狠狠躁免费观看2020 | 成人手机视频在线观看 | 国产成人lu在线视频 | 国产97在线观看 | 国产成人aa在线视频 | 日韩一区二区在线免费观看 | 国产手机在线国内精品 | 亚洲精品久久一区二区无卡 | 日本高清免费视频www | 亚洲第一网站免费视频 | 欧洲做人爱c欧美 | 久久久成人影院 | 亚洲久草| 国产特黄一级一片免费 |