简单描述下需求场景:
本来开发的页面在大部分手机里,都是竖向下来展开的,但现在市场上折叠手机越来越多,那么当用户翻转折叠手机,宽度变长了,原本我们的开发页面就会被拉大,显得不好看,所以需要前端针对折叠屏进行兼容,在没打开的时候正常显示,翻转打开的时候就把页面上的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,实际真机没测试过。
标签:function,屏中,scale,折叠,布局,innerWidth,竖向,window,var From: https://www.cnblogs.com/xiaozhu007/p/18525559