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

简单描述下需求场景:

  本来开发的页面在大部分手机里,都是竖向下来展开的,但现在市场上折叠手机越来越多,那么当用户翻转折叠手机,宽度变长了,原本我们的开发页面就会被拉大,显得不好看,所以需要前端针对折叠屏进行兼容,在没打开的时候正常显示,翻转打开的时候就把页面上的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,实际真机没测试过。

 

posted @ 2024-11-07 16:30  爱上大树的小猪  阅读(195)  评论(0)    收藏  举报