最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

移動端JS實現(xiàn)拖拽兩種方法解析

 更新時間:2020年10月12日 09:09:56   投稿:yaominghui  
這篇文章主要介紹了移動端JS實現(xiàn)拖拽兩種方法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

移動端的項目經(jīng)常會引入手勢庫來實現(xiàn)拖拽

不過如果只是一兩個頁面用到拖拽,再引入一個手勢庫就很不劃算

最近的項目中就有這么一個需求:

因為就這一個地方需要拖拽,所以我就沒有引入第三方庫

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

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

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

方案一:固定定位 fixed

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

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

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

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

1.1 創(chuàng)建遮罩

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

createModal (id) {
 let modal = document.getElementById(id)
 if (!modal) { // 在沒有遮罩的時候創(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事件的時候,首先創(chuàng)建遮罩

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

為了記錄起點信息,需要 data 中創(chuàng)建一個對象source,用于記錄點擊的位置 client,和初始定位坐標 start

handleTouchstart (e) { // 開始拖拽
 // 創(chuàng)建遮罩層
 this.createModal(this.modalID) // modalID 遮罩層的id,由外部定義
 let element = e.targetTouches[0]
 let target = e.target.cloneNode(true) // 拷貝目標元素
 target.id = this.copyID // copyID 拷貝元素的id,由外部定義
 // 記錄初始點擊位置 client,用于計算移動距離
 this.source.client = {
  x: element.clientX,
  y: element.clientY
 }
 // 算出目標元素的固定位置
 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 處理拖拽

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

用【當前鼠標點位置】減去【初始點擊位置】得到移動的距離

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

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

1.4 拖拽結(jié)束

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

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)
},

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

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

方案二:平移動畫translate

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

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

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

2.1 開始拖拽

開始拖拽的時候,只需要記錄起點坐標

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

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

2.2 處理拖拽

根據(jù)當前坐標和起點坐標,計算出距離,然后更新 translate 的坐標

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

2.3 拖拽結(jié)束

拖拽完成后,清除平移動畫

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

小結(jié):

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

但這個方法性能不高,應當少用

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

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 深入理解ES7的async/await的用法

    深入理解ES7的async/await的用法

    本篇文章主要介紹了深入理解ES7的async/await的用法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • 如何在js中計算兩個時間段重疊的時長問題詳解

    如何在js中計算兩個時間段重疊的時長問題詳解

    這篇文章主要給大家介紹了關于如何在js中計算兩個時間段重疊的時長問題的相關資料,判斷兩個時間段是否重疊可以通過比較兩個時間段的開始時間和結(jié)束時間來實現(xiàn),文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下
    2024-04-04
  • 基于jquery的高性能td和input切換并可修改內(nèi)容實現(xiàn)代碼

    基于jquery的高性能td和input切換并可修改內(nèi)容實現(xiàn)代碼

    在實際工作中,我們會碰到這樣一個情況。在頁面中顯示著100個數(shù)據(jù),同時用戶還希望他可以更改其中的數(shù)據(jù),普通的方式可能如下
    2011-01-01
  • Array.prototype.concat不是通用方法反駁[譯]

    Array.prototype.concat不是通用方法反駁[譯]

    ECMAScript 5.1規(guī)范中指出,數(shù)組方法concat是通用的(generic).本文反駁了這一結(jié)論,因為實際上并不是這樣的
    2012-09-09
  • 如何豐富alt屬性的顯示效果

    如何豐富alt屬性的顯示效果

    如何豐富alt屬性的顯示效果...
    2007-01-01
  • 原生JavaScript實現(xiàn)進度條

    原生JavaScript實現(xiàn)進度條

    這篇文章主要為大家詳細介紹了原生JavaScript實現(xiàn)進度條,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-02-02
  • 使用js畫圖之畫切線

    使用js畫圖之畫切線

    這篇文章主要介紹了使用js繪制幾何圖形系列教程中的畫切線篇,非常方便我們好好熟悉理解javascript,推薦給大家
    2015-01-01
  • Bootstrap CSS布局之按鈕

    Bootstrap CSS布局之按鈕

    這篇文章主要介為大家詳細紹了Bootstrap CSS布局之按鈕的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • Javascript原生ajax請求代碼實例

    Javascript原生ajax請求代碼實例

    這篇文章主要介紹了Javascript原生ajax請求代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • 一文了解你不知道的JavaScript異步篇

    一文了解你不知道的JavaScript異步篇

    這篇文章主要為大家詳細介紹了一些你不知道的JavaScript異步相關知識,文中的示例代碼講解詳細,對我們學習JavaScript有一定幫助,感興趣的可以跟隨小編一起學習一下
    2022-11-11

最新評論

普兰县| 额尔古纳市| 北海市| 共和县| 东乌珠穆沁旗| 兰溪市| 全州县| 田林县| 依安县| 广昌县| 沙河市| 汾阳市| 曲阳县| 文化| 尚义县| 京山县| 邢台县| 桂阳县| 武冈市| 深水埗区| 保定市| 巫溪县| 拜泉县| 永川市| 鄯善县| 泰来县| 龙川县| 祁连县| 双城市| 九台市| 营口市| 长海县| 霍林郭勒市| 青岛市| 双桥区| 信阳市| 衡东县| 封丘县| 凌云县| 山丹县| 兴宁市|