美文网首页
移动端沉浸式探测

移动端沉浸式探测

作者: yibuyisheng | 来源:发表于2018-12-18 21:43 被阅读16次

    背景

    有时候我们的 H5 应用既要能运行在各种容器内,也要能运行在浏览器中,并且在容器中尽量采用沉浸式方式呈现。

    在容器中,是需要根据不同容器来设置不同的状态栏背景色的,不然就很可能看不见系统展示在状态栏上的文字了。而在浏览器中,不采用沉浸式方式呈现,因此是不需要理会的。

    方案

    可以借助 window.innerHeight 和 window.screen.height 来判断,关于这俩的含义,可以在 MDN 上查到。

    实际上,在移动端,H5 页面中,window.screen.height 拿到的是逻辑像素值,window.innerHeight 拿到的是物理像素值或者逻辑像素值。并且,在页面初始化过程中,window.innerHeight 有可能会发生变化(最后稳定的值才是正确的)。

    为了应对上述情况,必须要在初始化的时候不停地检查,直到最终拿到稳定结果。

    《First, Understand Your Screen》

    代码

    async function isImmersion() {
      const check = () => {
        // windowHeight 是期望存储视口的逻辑像素值
        let windowHeight = window.innerHeight / window.devicePixelRatio;
        if (
          // 如果 window.screen.height 比 window.innerHeight 大,
          // 说明 window.innerHeight 肯定是逻辑像素值。
          window.screen.height - window.innerHeight > 0
          && window.screen.height - window.innerHeight < 130
        ) {
          windowHeight = window.innerHeight;
        }
    
        // iPhone X 飞猪下面 window.screen.height 和 windowHeight 差一丢丢(其余场景都可以用相等来判断)。
        return window.screen.height - windowHeight < 1;
      };
    
      if (document.readyState !== 'complete') {
        await new Promise((resolve) => {
          document.addEventListener('DOMContentLoaded', resolve);
        });
      }
    
      return new Promise((resolve, reject) => {
        const checkResults = [];
        setTimeout(() => {
          checkResults.push(check());
          const length = checkResults.length;
          if (
            length >= 3
            && checkResults[length - 1] === checkResults[length - 2]
            && checkResults[length - 2] === checkResults[length - 3]
          ) {
            resolve(checkResults[length - 1]);
          }
        }, 100);
    
        setTimeout(() => {
          reject(new Error('Check immersion timeout.'));
        }, 1000);
      });
    }
    
    

    相关文章

      网友评论

          本文标题:移动端沉浸式探测

          本文链接:https://www.haomeiwen.com/subject/imerkqtx.html