关于把竖向单个布局在鸿蒙等折叠手机屏中显示成双向布局
简单描述下需求场景:
本来开发的页面在大部分手机里,都是竖向下来展开的,但现在市场上折叠手机越来越多,那么当用户翻转折叠手机,宽度变长了,原本我们的开发页面就会被拉大,显得不好看,所以需要前端针对折叠屏进行兼容,在没打开的时候正常显示,翻转打开的时候就把页面上的div结合百分比和flex布局展开成两列。改善体验。
没做兼容之前的折叠屏效果如下:
做了兼容后,同样的屏幕大小打开效果如下:
1. 首先更改全局rem的计算方式,按照vue和react项目,都是放在index.html的js中,项目进入加载逻辑。
以前正常手机都是1,但折叠屏情况下,要按0.5算,小一半屏幕
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | function resize() { ! function (e) { function t(a) { if (i[a]) return i[a].exports; var n = i[a] = { exports: {}, id: a, loaded: !1 }; return e[a].call(n.exports, n, n.exports, t), n.loaded = !0, n.exports } var i = {}; return t.m = e, t.c = i, t.p = "" , t(0) }([ function (e, t) { "use strict" ; Object.defineProperty(t, "__esModule" , { value: !0 }); var i = window; var benchmarkWidth = 750; t[ "default" ] = i.flex = function (e, t) { var a = e || 100 , n = t || 1 , r = i.document , o = navigator.userAgent , d = o.match(/Android[\S\s]+AppleWebkit\/(\d{3})/i) , l = o.match(/U3\/((\d+|\.){5,})/i) , c = l && parseInt(l[1].split( "." ).join( "" ), 10) >= 80 , p = navigator.appVersion.match(/(iphone|ipad|ipod)/gi) , s = i.devicePixelRatio || 1; p || d && d[1] > 534 || c || (s = 1); var u = 1 / s , m = r.querySelector( 'meta[name="viewport"]' ); m || (m = r.createElement( "meta" ), m.setAttribute( "name" , "viewport" ), r.head.appendChild(m)); m.setAttribute( "content" , "width=device-width,user-scalable=no,initial-scale=" + u + ",maximum-scale=" + u + ",minimum-scale=" + u); var offsetWidth = i.document.documentElement.offsetWidth; let percentage = 1 // 宽屏、折叠屏缩小页面比例 try { const scale = window.innerWidth / window.innerHeight if (scale >= 0.9) { percentage = 0.5 } } catch { } r.documentElement.style.fontSize = offsetWidth / benchmarkWidth * e * percentage + "px" ; window.screenfontSize = offsetWidth / benchmarkWidth * e * percentage } , e.exports = t[ "default" ] } ]); flex(100, 1); } |
同时要在页面中做监听
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | resize() var pageWidth = window.innerWidth var t = null var fn = 'orientationchange' in window ? 'orientationchange' : 'resize' ; window.addEventListener(fn, function () { clearTimeout(t) t = setTimeout( function () { var newPageWidth = window.innerWidth if (pageWidth !== newPageWidth) { pageWidth = newPageWidth resize() } }, 300) }, false ); |
2. 在对应要做兼容的页面中,进入页面同样执行 window.innerWidth / window.innerHeight 算出当前屏幕对应比例值,这里以react为例子,vue转换下写法一样的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | import React, { useState, useEffect } from 'react' ; function MyComponent() { const [hmScale, setHmScale] = useState(window.innerWidth / window.innerHeight); // 比例值 // 兼容折叠屏等系列获取scale const getWidthScreen = () => { // 监听开始初始化最新值 setHmScale(window.innerWidth / window.innerHeight) // 二次预防措施 let t = null let pageWidth = window.innerWidth clearTimeout(t) t = setTimeout( function () { let newPageWidth = window.innerWidth if (pageWidth !== newPageWidth) { pageWidth = newPageWidth setHmScale(window.innerWidth / window.innerHeight) } }, 300) } useEffect(() => { window.addEventListener( 'resize' , getWidthScreen) return () => { // 卸载时移除监听 window.removeEventListener( 'resize' , getWidthScreen) } }, []) return ( <div> <div className={`detail-page ${hmScale >= 0.9 ? 'width-screen' : '' }`}> <div>1 </div> <div>2 </div> </div> </div> ); } export default MyComponent; |
3. 得出scale后更改原本布局下的div样式,用百分比计算减去对应外边距的rem,再用flx布局就可以完成响应式折叠屏兼容。css参考如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | .detail-page { &.width- screen { display : flex; flex-wrap: wrap; & > div { width : calc(( 100% - . 2 rem) / 2 ); &:nth-child(even) { margin-left : . 2 rem; } } } } |
以上则就是兼容折叠屏的基本方法,如果是三屏,理论上就除以3,实际真机没测试过。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)