Vue中怎么使用DrawerLayout側(cè)滑菜單組件,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。
在塔城等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站建設(shè)、成都做網(wǎng)站 網(wǎng)站設(shè)計(jì)制作定制網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計(jì),成都全網(wǎng)營(yíng)銷,外貿(mào)營(yíng)銷網(wǎng)站建設(shè),塔城網(wǎng)站建設(shè)費(fèi)用合理。
HTML結(jié)構(gòu)
頁面結(jié)構(gòu)很簡(jiǎn)單,一個(gè)抽屜,一個(gè)主容器,內(nèi)容可以利用slot支持外部自行定制。
<div class="drawer-layout"> <!--抽屜--> <div class="drawer-wrap"> <slot name="drawer"></slot> </div> <!--主容器--> <div class="content-wrap"> <!--遮罩--> <div class="drawer-mask"></div> <slot name="content"></slot> </div> </div>
抽屜一開始是隱藏在左側(cè)屏幕外的,故設(shè)置 left:-100% 使其整個(gè)都藏在外部
使用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坐標(biāo)記為 startX ,滑動(dòng)中手指的位置x坐標(biāo)記為 nowX ,drawer的x坐標(biāo)偏移量記為 startPos
let startX, nowX, startPos;
觸發(fā) touchstart 時(shí),記錄起始位置并綁定 touchmove ,注意:如果是 mouseEvent ,通過 e.clientX 來獲取當(dāng)前的x坐標(biāo),如果是 touchEvent ,要通過 e.changedTouches[0].clientX 來獲取x坐標(biāo)
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; //滑動(dòng)中手指的位置x坐標(biāo)
let pos = startPos + nowX - startX;
pos = Math.min(width, pos); //不能超過滑動(dòng)最大值
pos = Math.max(0, pos); //不能小于0
this.pos = pos; //設(shè)置滾動(dòng)距離為拖動(dòng)的距離
}.bind(this);那么,手指滑動(dòng)的距離就是 nowX - startX ,當(dāng)前drawer的位置為 startPos + nowX - startX ,這樣抽屜已經(jīng)跟隨手指向右移動(dòng)了,并且不會(huì)超過我們?cè)O(shè)置的拖動(dòng)最大值。
區(qū)分垂直滑動(dòng)和水平滑動(dòng)
接下來你會(huì)發(fā)現(xiàn)一個(gè)問題,當(dāng)手指垂直滾動(dòng)主內(nèi)容時(shí),向右滑動(dòng)手指也會(huì)拖出抽屜,這時(shí)應(yīng)該做一件事:區(qū)分垂直滑動(dòng)和水平滑動(dòng)
當(dāng)然,辦法有很多,這里先介紹一種利用三角函數(shù)來判定的方法
假設(shè),上圖中的每個(gè)箭頭是手指滑動(dòng)的方向,綠色箭頭代表可以拖出抽屜,紅色箭頭代表不可以拖出(注意,紅色箭頭也是有x坐標(biāo)的偏移量的)。即當(dāng)不可以拖出抽屜時(shí),應(yīng)觸發(fā)默認(rèn)事件,比如垂直方向的滾動(dòng)等等。
當(dāng)手指按下觸發(fā) touchstart 時(shí),記錄初始位置P 0 ;當(dāng)滑動(dòng)手指時(shí),觸發(fā)的第一次 touchmove 時(shí),記錄位置P 1 ,我們將P 0 到P 1 的矢量記為S(原諒我這個(gè)靈魂畫手)
這時(shí)候很容易看出,∠θ大于某個(gè)值時(shí),比如30度,就可能是垂直方向的滾動(dòng)操作而不是拖動(dòng)抽屜。所以,可以根據(jù) y/x>tan30°
得到判斷條件:
if (isVerticle === undefined) isVerticle = Math.abs(nowY - startY) / Math.abs(nowX - startX) > (Math.sqrt(3) / 3);
當(dāng) isVerticle 為 true 時(shí),不執(zhí)行drawer的拖動(dòng)
讓Drawer動(dòng)起來
我們使用css3的 transition 屬性使drawer具有過渡動(dòng)畫效果,這里寫一個(gè) moving 類
.moving transition transform .3s ease
別忘了加上class綁定,拖動(dòng)時(shí)是不需要過渡動(dòng)畫的(要跟隨手指),而松開手指時(shí)才需要過渡動(dòng)畫。
<div class="drawer-wrap" :class="{'moving':moving,'will-change':willChange}"
:>
<slot name="drawer"></slot>
</div>所以綁定 touchend 事件的方法時(shí)要做這些步驟
const removeDrag = function (e) {
if (isVerticle !== undefined) {
if (!isVerticle) {//當(dāng)判定為抽屜拖動(dòng)才進(jìn)入
let pos = this.pos;
this.visible = pos > width * 3 / 5 //當(dāng)前位置如果大于總寬度的3/5就判定為全部展開抽屜,否則將抽屜彈回隱藏
if (this.pos > 0 && this.pos < width) this.moving = true;//如果位置已經(jīng)處于最小值或最大值處,不需要有動(dòng)畫效果了
}
this.pos = this.visible ? width : 0;
}
if (!this.moving) {
this.willChange = false; //留個(gè)懸念
}
isVerticle = undefined;
//取消touchmove和touchend事件綁定
document.removeEventListener(mouseEvents.move, drag, false);
document.removeEventListener(mouseEvents.up, removeDrag, false);
}.bind(this);上面你可能發(fā)現(xiàn)代碼里有個(gè) this.willChange = false ,它是干啥的捏?下面我們請(qǐng)出css的 will-change 大法
.will-change
will-change transform
CSS 屬性 will-change 為web開發(fā)者提供了一種告知瀏覽器該元素會(huì)有哪些變化的方法,這樣瀏覽器可以在元素屬性真正發(fā)生變化之前提前做好對(duì)應(yīng)的優(yōu)化準(zhǔn)備工作。 這種優(yōu)化可以將一部分復(fù)雜的計(jì)算工作提前準(zhǔn)備好,使頁面的反應(yīng)更為快速靈敏。
其實(shí)是我們?cè)?touchstart 可以預(yù)先告知瀏覽器抽屜可能要發(fā)生位移
const initDrag = function (e) {
//...
this.willChange = true;
}.bind(this);當(dāng)然最后別忘了在 transitionend 事件后把 transition 和 will-change 去掉,讓瀏覽器歇一會(huì)兒~
還有什么可以優(yōu)化的?
上面說的已經(jīng)基本上把主要功能實(shí)現(xiàn)了,但是這其中還有沒有哪里可以優(yōu)化的?
咦? passive
是什么鬼?
網(wǎng)站使用被動(dòng)事件偵聽器以提升滾動(dòng)性能,在您的觸摸和滾輪事件偵聽器上設(shè)置 passive 選項(xiàng)可提升滾動(dòng)性能具體看這里
原來這是現(xiàn)代瀏覽器的一個(gè)新特性,我們需要以新的方式來綁定我們的touch事件,當(dāng)然首先先檢測(cè)一下是否支持 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);看完上述內(nèi)容,你們掌握Vue中怎么使用DrawerLayout側(cè)滑菜單組件的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!
文章標(biāo)題:Vue中怎么使用DrawerLayout側(cè)滑菜單組件
瀏覽地址:http://chinadenli.net/article36/jpcpsg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、Google、營(yíng)銷型網(wǎng)站建設(shè)、搜索引擎優(yōu)化、網(wǎng)站營(yíng)銷、面包屑導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)