本文介紹一個簡單的DrawerLayout(類似Android的DrawerLayout)佈局元件的實現,基於Vue.js側滑選單元件的實現程式碼大家透過本文一起學習吧
本文介紹一個簡單的DrawerLayout(類似Android的DrawerLayout)佈局元件的實現,基於Vue.js。介紹的內容已經製作成 vue-drawer-layout 組件。
前言
大家有興趣先用手機掃一掃這個二維碼,或是點我
#然後點擊頁面中左上角的頭像打開drawer或向右向左拖拽,就可以看到下面gif的效果,打開自己的手機QQ,是不是很像:)
Google官方把這種佈局叫做DrawerLayout(抽屜式導覽列)。那我們要如何實現呢,好了正片開始!
HTML結構
頁面結構很簡單,一個抽屜,一個主容器,內容可以利用slot支援外部自行自訂。
<p class="drawer-layout"> <!--抽屉--> <p class="drawer-wrap"> <slot name="drawer"></slot> </p> <!--主容器--> <p class="content-wrap"> <!--遮罩--> <p class="drawer-mask"></p> <slot name="content"></slot> </p> </p>
抽屜一開始是隱藏在左側螢幕外的,故設定left:-100% 使其整個都藏在外部
使用Touch
首先,判斷瀏覽器是否支援touchEvent
let isTouch = 'ontouchstart' in window; let mouseEvents = isTouch ? { down: 'touchstart', move: 'touchmove', up: 'touchend', over: 'touchstart', out: 'touchend' } : { down: 'mousedown', move: 'mousemove', up: 'mouseup', over: 'mouseover', out: 'mouseout' };
#綁定touchdown 事件
document.addEventListener(mouseEvents.down, initDrag, false);
先定義一些變量,手指按下的x坐標記為startX ,滑動中手指的位置x坐標記為nowX ,drawer的x坐標偏移量記為startPos
let startX, nowX, startPos;
觸發touchstart 時,記錄起始位置並綁定touchmove ,注意:如果是mouseEvent ,透過e.clientX 來取得目前的x座標,如果是touchEvent ,要透過e.changedTouches[0].clientX 來取得x座標
const initDrag = function (e) { startX = e.clientX || e.changedTouches[0].clientX; //记录手指按下的位置 startPos = this.pos; //记录drawer的上次位置 document.addEventListener(mouseEvents.move, drag, false); document.addEventListener(mouseEvents.up, removeDrag, false); }.bind(this); const drag = function (e) { nowX = e.clientX || e.changedTouches[0].clientX; //滑动中手指的位置x坐标 let pos = startPos + nowX - startX; pos = Math.min(width, pos); //不能超过滑动最大值 pos = Math.max(0, pos); //不能小于0 this.pos = pos; //设置滚动距离为拖动的距离 }.bind(this);
那麼,手指滑動的距離就是nowX - startX ,目前drawer的位置為startPos nowX - startX ,這樣抽屜已經跟著手指向右移動了,並且不會超過我們設定的拖曳最大值。
區分垂直滑動和水平滑動
接下來你會發現一個問題,當手指垂直滾動主內容時,向右滑動手指也會拖出抽屜,這時應該要做一件事:區分垂直滑動和水平滑動
當然,辦法有很多,這裡先介紹一種利用三角函數來判定的方法
#
假設,上圖中的每個箭頭是手指滑動的方向,綠色箭頭代表可以拖出抽屜,紅色箭頭代表不可以拖出(注意,紅色箭頭也是有x座標的偏移量的)。即當不可以拖出抽屜時,應觸發預設事件,例如垂直方向的滾動等等。
當手指按下觸發touchstart 時,記錄初始位置P 0 ;當滑動手指時,觸發的第一次touchmove 時,記錄位置P 1 ,我們將P 0 到P 1 的向量記為S (原諒我這個靈魂畫手)
這時候很容易看出,∠θ大於某個值時,例如30度,就可能是垂直方向的滾動操作而不是拖曳抽屜。所以,可以根據y/x>tan30°
得到判斷條件:
if (isVerticle === undefined) isVerticle = Math.abs(nowY - startY) / Math.abs(nowX - startX) > (Math.sqrt(3) / 3);
當isVerticle 為true 時,不執行drawer的拖曳
#讓Drawer動起來
我們使用css3的transition 屬性讓drawer具有過渡動畫效果,這裡寫一個moving 類別
.moving transition transform .3s ease
別忘了加上class綁定,拖曳時是不需要過渡動畫的(要跟著手指),而鬆開手指時才需要轉換動畫。
<p class="drawer-wrap" :class="{'moving':moving,'will-change':willChange}" :style="{width:`${width}px`,left:`-${width)}px`,transform:`translate3d(${pos}px,0,0)`}"> <slot name="drawer"></slot> </p>
所以綁定 touchend 事件的方法時要做這些步驟
const removeDrag = function (e) { if (isVerticle !== undefined) { if (!isVerticle) {//当判定为抽屉拖动才进入 let pos = this.pos; this.visible = pos > width * 3 / 5 //当前位置如果大于总宽度的3/5就判定为全部展开抽屉,否则将抽屉弹回隐藏 if (this.pos > 0 && this.pos < width) this.moving = true;//如果位置已经处于最小值或最大值处,不需要有动画效果了 } this.pos = this.visible ? width : 0; } if (!this.moving) { this.willChange = false; //留个悬念 } isVerticle = undefined; //取消touchmove和touchend事件绑定 document.removeEventListener(mouseEvents.move, drag, false); document.removeEventListener(mouseEvents.up, removeDrag, false); }.bind(this);
上面你可能發現程式碼裡有個 this.willChange = false ,它是乾啥的捏?下面我們請出css的will-change 大法
.will-change
will-change transform
CSS 屬性will-change 為web開發者提供了一種告知瀏覽器該元素會有哪些變化的方法,這樣瀏覽器可以在元素屬性真正改變之前提前做好對應的最佳化準備。這種優化可以將一部分複雜的計算工作提前準備好,使頁面的反應更為快速靈敏。
其實是我們在touchstart 可以預先告知瀏覽器抽屜可能要發生位移
const initDrag = function (e) { //... this.willChange = true; }.bind(this);
當然最後別忘了在transitionend 事件後把transition 和will-change 去掉,讓瀏覽器歇一會兒~
還有什麼可以優化的?
上面說的已經基本上把主要功能實現了,但是這其中還有沒有哪裡可以優化的?
咦? passive
是什麼鬼?
网站使用被动事件侦听器以提升滚动性能,在您的触摸和滚轮事件侦听器上设置 passive 选项可提升滚动性能具体看这里
原来这是现代浏览器的一个新特性,我们需要以新的方式来绑定我们的touch事件,当然首先先检测一下是否支持 passive
const supportsPassive = (() => { let supportsPassive = false; try { const opts = Object.defineProperty({}, 'passive', { get: function () { supportsPassive = true; } }); window.addEventListener("test", null, opts); } catch (e) { } return supportsPassive; })();
于是我们的绑定事件代码变成这样
document.addEventListener(mouseEvents.move, drag, supportsPassive ? {passive: true} : false);
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
在React Native中使用prop-types如何实现属性确认
以上是在Vue中如何實現側滑選單元件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

記事本++7.3.1
好用且免費的程式碼編輯器

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

禪工作室 13.0.1
強大的PHP整合開發環境