关于把竖向单个布局在鸿蒙等折叠手机屏中显示成双向布局

简单描述下需求场景:

  本来开发的页面在大部分手机里,都是竖向下来展开的,但现在市场上折叠手机越来越多,那么当用户翻转折叠手机,宽度变长了,原本我们的开发页面就会被拉大,显得不好看,所以需要前端针对折叠屏进行兼容,在没打开的时候正常显示,翻转打开的时候就把页面上的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% - .2rem) / 2);
 
      &:nth-child(even) {
        margin-left: .2rem;
      }
    }
  }
}

  以上则就是兼容折叠屏的基本方法,如果是三屏,理论上就除以3,实际真机没测试过。

 

posted @   爱上大树的小猪  阅读(95)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示