詳解小程序橫屏方案對(duì)比
前言
隨著小程序api開放的功能日漸增多,小程序可以做到的功能和展現(xiàn)形式也越來越多,其中橫屏的展現(xiàn)形式就是其中的一種,而實(shí)現(xiàn)橫屏的方案也有多種,但是每種方案都有一定的缺陷,恰巧最近也在橫屏方案上踩了不少坑,接下來就來和大家分享一下小程序的不同橫屏方案的優(yōu)劣(踩坑心得)
組件自帶橫屏方法
小程序中的媒體組件一般都會(huì)提供全屏的方法,而且全屏方法中會(huì)提供一個(gè)direction的全屏參數(shù),可以通過這全屏參數(shù)將小程序旋轉(zhuǎn)90度橫屏展示,這是小程序中最簡(jiǎn)單的橫屏方法。
這個(gè)方法優(yōu)點(diǎn)在于調(diào)用的組件全屏方法做的橫屏,不需要考慮頭部導(dǎo)航欄的膠囊按鈕的顯示問題,媒體組件在做全屏顯示時(shí),膠囊按鈕會(huì)自動(dòng)隱藏不見,同時(shí)大多數(shù)媒體組件都已經(jīng)支持了同層渲染,可以通過z-index調(diào)整組件層級(jí),因此用此法在橫屏布局時(shí)可以在媒體組件上覆蓋其他組件布局
缺點(diǎn):這個(gè)方法的缺點(diǎn)也很明顯,就是只能使用媒體相關(guān)組件才能有橫屏的全屏,場(chǎng)景很單一,如果不是媒體組件或者不想全屏,那么對(duì)不起,此法不可用
計(jì)算加速度判斷橫屏
這個(gè)方法是之前有人發(fā)在微信社區(qū)里的一個(gè)方法,通過小程序提供的wx.onAccelerometerChange方法監(jiān)聽設(shè)備在x、y、z軸上的加速度,通過返回的重力加速度計(jì)算設(shè)備的旋轉(zhuǎn)角度,下面貼出代碼給大家參考:
// 0為豎屏,1為橫屏
let lastState = 0;
let lastTime = Date.now();
wx.startAccelerometer();
wx.onAccelerometerChange((res) => {
const now = Date.now();
// 500ms檢測(cè)一次
if (now - lastTime < 500) {
return;
}
lastTime = now;
let nowState;
// 57.3 = 180 / Math.PI
const Roll = Math.atan2(-res.x, Math.sqrt(res.y * res.y + res.z * res.z)) * 57.3;
const Pitch = Math.atan2(res.y, res.z) * 57.3;
// console.log('Roll: ' + Roll, 'Pitch: ' + Pitch)
// 橫屏狀態(tài)
if (Roll > 50) {
if ((Pitch > -180 && Pitch < -60) || (Pitch > 130)) {
nowState = 1;
}else {
nowState = lastState;
}
}else if ((Roll > 0 && Roll < 30) || (Roll < 0 && Roll > -30)) {
let absPitch = Math.abs(Pitch);
// 如果手機(jī)平躺,保持原狀態(tài)不變,40容錯(cuò)率
if ((absPitch > 140 || absPitch < 40)) {
nowState = lastState;
}else if (Pitch < 0) {/*收集豎向正立的情況*/
nowState = 0;
}else {
nowState = lastState;
}
}
else {
nowState = lastState;
}
// 狀態(tài)變化時(shí),觸發(fā)
if (nowState !== lastState) {
lastState = nowState;
if (nowState === 1) {
console.log('change:橫屏');
}else {
console.log('change:豎屏');
}
}
});
更多的實(shí)現(xiàn)細(xì)節(jié)可以前往社區(qū)帖子查看,這個(gè)方法個(gè)人實(shí)際嘗試過,確實(shí)可以判斷設(shè)備處在橫屏還是豎屏
優(yōu)點(diǎn):這個(gè)方法的優(yōu)點(diǎn)在于可以監(jiān)聽到設(shè)備的橫豎屏情況,然后根據(jù)項(xiàng)目需要展示不同橫豎屏布局,自由度很高
缺點(diǎn):這個(gè)方法的缺點(diǎn)在于在頁面內(nèi)容橫屏?xí)r無法使頭部導(dǎo)航欄的膠囊按鈕橫屏展示,因?yàn)轭^部導(dǎo)航欄的膠囊按鈕始終是固定屏幕右上角不動(dòng)的,這樣會(huì)使得橫屏效果有點(diǎn)奇怪,橫屏是導(dǎo)航欄固定在左邊是豎屏?xí)r的布局,除非橫屏的布局是媒體組件的全屏,這樣就能遮住膠囊按鈕,自己自定義一個(gè)頭部導(dǎo)航,這樣就不會(huì)顯得布局奇怪
pageOrientation
pageOrientation是小程序提供的配置屬性,可以設(shè)置當(dāng)前頁面是橫屏展示、豎屏展示、或者自動(dòng)旋轉(zhuǎn),同時(shí)提供一個(gè)onResize的監(jiān)聽方法,當(dāng)屏幕發(fā)生旋轉(zhuǎn)時(shí)會(huì)觸發(fā)onResize的回調(diào),并且會(huì)在回調(diào)中返回當(dāng)前是橫屏還是豎屏以及相應(yīng)區(qū)域的大小。
優(yōu)點(diǎn):配置即可,手機(jī)旋轉(zhuǎn)觸發(fā)監(jiān)聽事件,返回屏幕旋轉(zhuǎn)后的寬高和當(dāng)前橫豎屏情況,橫屏?xí)r膠囊按鈕會(huì)自動(dòng)旋轉(zhuǎn),這樣頁面布局就不會(huì)有上一個(gè)方法所提及的怪異布局
缺點(diǎn):
- 由于是配置形式,沒辦法主動(dòng)調(diào)用,只能被動(dòng)監(jiān)聽
- 當(dāng)用戶將手機(jī)允許旋轉(zhuǎn)關(guān)閉后,onResize的監(jiān)聽方法就不會(huì)觸發(fā)
- 由于小程序大多數(shù)時(shí)候使用的是rpx的單位,是一個(gè)基于響應(yīng)區(qū)域大小的動(dòng)態(tài)計(jì)算的單位,當(dāng)屏幕發(fā)生旋轉(zhuǎn)后,假設(shè)豎屏旋轉(zhuǎn)到橫屏,豎屏?xí)r響應(yīng)區(qū)域?yàn)?75 667,到了橫屏?xí)r響應(yīng)區(qū)域?yàn)?67 375,此時(shí)onResize回調(diào)還沒觸發(fā),此時(shí)的頁面布局是豎屏的布局,但是由于響應(yīng)區(qū)域發(fā)生變化375 667到667 375,rpx就會(huì)重新計(jì)算,此時(shí)頁面的布局會(huì)突然變大,然后onResize回調(diào)觸發(fā)后才會(huì)變?yōu)闄M屏布局,會(huì)有布局閃現(xiàn)錯(cuò)亂的情況
- width:100%或者width:100vw這類的占滿全部的樣式也會(huì)出現(xiàn)問題,同樣假設(shè)從豎屏切換到橫屏,當(dāng)豎屏切換的橫屏?xí)r,此時(shí)width:100%的樣式,計(jì)算100%的寬度還是豎屏?xí)r的375,不會(huì)立即切換到橫屏?xí)r的667,因此切換到橫屏?xí)r的一瞬間,能看到原來100%的樣式,此時(shí)并沒有占滿100%,閃了一下375之后,然后才會(huì)占滿,假設(shè)我們自定義的頂部標(biāo)題欄,用了width:100%,那么我橫屏?xí)r就會(huì)發(fā)現(xiàn),標(biāo)題欄寬度只有一半,然后才會(huì)占滿
橫屏?xí)r響應(yīng)區(qū)域變化產(chǎn)生布局變化的解決辦法
這個(gè)解決辦法只能解決橫屏?xí)r由于響應(yīng)區(qū)域變化導(dǎo)致rpx重新的計(jì)算渲染的問題,既然rpx會(huì)在響應(yīng)區(qū)域變化時(shí)重新計(jì)算渲染,那我們最直接粗暴簡(jiǎn)單的方法就是不使用動(dòng)態(tài)計(jì)算的單位px,這樣就不會(huì)在橫屏?xí)r重新渲染計(jì)算,但是這樣也有一個(gè)問題,就是在不同屏幕的大小的手機(jī)下也沒法動(dòng)態(tài)計(jì)算了
那有沒有其他的更好辦法呢?vmax、vmin這兩個(gè)單位應(yīng)該平時(shí)用的不多,個(gè)人也很少用,如果不是這次寫小程序橫屏,也不會(huì)關(guān)注到它
vmin:取值是當(dāng)前vw和vh中較小的值,vmax:取值是當(dāng)前vw和vh中較大的值
在豎屏?xí)r100vmin=375px,到了橫屏?xí)r100vmin=375px,這樣就能保證在橫豎屏切換的時(shí)候內(nèi)容大小不變,在小程序中使用calc(vmin/7.5),假設(shè)大小為10px,那么css為calc(10vmin/7.5),如果你嫌這么寫麻煩,同時(shí)使用的是vs code,那么可以創(chuàng)建一個(gè)全局User Snippets:
"rpx to vmin" : {
"prefix": "tovmin",
"body": ["calc($0vmin / 7.5)"],
"description": "rpx to vmin"
}
這樣在寫css時(shí)直接寫tomin就會(huì)將calc($0vmin / 7.5)輸出

總結(jié)
小程序中的橫屏方案總是有這樣或者那樣的問題,并沒有完美的解決方案,有時(shí)還是小程序自身原因?qū)е碌?,我們能做的只是尋找解決辦法或者換個(gè)交互設(shè)計(jì),這篇文章的目的就是希望對(duì)大家在做橫屏方案時(shí)提供一點(diǎn)幫助,少踩坑,這是我的踩坑經(jīng)歷,提供給大家借鑒,同時(shí)也有我的一些解決辦法,如果大家有更好的方案,可以一起學(xué)習(xí)。
到此這篇關(guān)于詳解小程序橫屏方案對(duì)比的文章就介紹到這了,更多相關(guān)小程序橫屏內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
TypeScript與JavaScript多方面闡述對(duì)比相同點(diǎn)和區(qū)別
TypeScript和JavaScript在開發(fā)交互式網(wǎng)頁方面有許多相似之處,在提供TypeScript與 JavaScript的直接比較時(shí),我們可以說JavaScript是一種輕量級(jí)的解釋型動(dòng)態(tài)語言,用于增強(qiáng)HTML網(wǎng)頁,TypeScript是JavaScript的增強(qiáng)版,這意味著TypeScript是JavaScript和其他一些特性的組合2024-07-07
JS打開層/關(guān)閉層/移動(dòng)層動(dòng)畫效果的實(shí)例代碼
JS打開層/關(guān)閉層/移動(dòng)層動(dòng)畫效果的實(shí)例代碼,需要的朋友可以參考一下2013-05-05
JavaScript實(shí)現(xiàn)文本目標(biāo)字符替換和一鍵全部替換
這篇文章主要介紹了JavaScript實(shí)現(xiàn)文本目標(biāo)字符替換和一鍵全部替換,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-06-06
js window.addEventListener實(shí)際案例
window.addEventListener 是 JavaScript 中的一個(gè)方法,用于向指定對(duì)象添加事件監(jiān)聽器,下面通過本文給大家介紹js window.addEventListener的實(shí)際案例,感興趣的朋友跟隨小編一起看看吧2024-12-12
分析javascript中9 個(gè)常見錯(cuò)誤阻礙你進(jìn)步
這篇文章主要介紹了分析javascript中9 個(gè)常見錯(cuò)誤阻礙你進(jìn)步的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下2017-09-09
JS實(shí)現(xiàn)圖片平面旋轉(zhuǎn)的方法
這篇文章主要介紹了JS實(shí)現(xiàn)圖片平面旋轉(zhuǎn)的方法,涉及JavaScript操作頁面元素樣式動(dòng)態(tài)變換的相關(guān)技巧,需要的朋友可以參考下2016-03-03
JS在一定時(shí)間內(nèi)跳轉(zhuǎn)頁面及各種刷新頁面的實(shí)現(xiàn)方法
這篇文章主要介紹了JS在一定時(shí)間內(nèi)跳轉(zhuǎn)頁面及各種刷新頁面的實(shí)現(xiàn)方法的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-05-05

