關於把豎向單個佈局在鴻蒙等摺疊手機屏中顯示成雙向佈局

爱上大树的小猪發表於2024-11-07

簡單描述下需求場景:

  本來開發的頁面在大部分手機裡,都是豎向下來展開的,但現在市場上摺疊手機越來越多,那麼當使用者翻轉折疊手機,寬度變長了,原本我們的開發頁面就會被拉大,顯得不好看,所以需要前端針對摺疊屏進行相容,在沒開啟的時候正常顯示,翻轉開啟的時候就把頁面上的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,實際真機沒測試過。

相關文章