关于把竖向单个布局在鸿蒙等折叠手机屏中显示成双向布局
简单描述下需求场景:
本来开发的页面在大部分手机里,都是竖向下来展开的,但现在市场上折叠手机越来越多,那么当用户翻转折叠手机,宽度变长了,原本我们的开发页面就会被拉大,显得不好看,所以需要前端针对折叠屏进行兼容,在没打开的时候正常显示,翻转打开的时候就把页面上的div结合百分比和flex布局展开成两列。改善体验。
没做兼容之前的折叠屏效果如下:

做了兼容后,同样的屏幕大小打开效果如下:

1. 首先更改全局rem的计算方式,按照vue和react项目,都是放在index.html的js中,项目进入加载逻辑。
以前正常手机都是1,但折叠屏情况下,要按0.5算,小一半屏幕
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);
}
同时要在页面中做监听
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转换下写法一样的
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参考如下:
.detail-page {
&.width-screen {
display: flex;
flex-wrap: wrap;
& > div {
width: calc((100% - .2rem) / 2);
&:nth-child(even) {
margin-left: .2rem;
}
}
}
}
以上则就是兼容折叠屏的基本方法,如果是三屏,理论上就除以3,实际真机没测试过。

浙公网安备 33010602011771号