移动端沉浸式探测

背景

有时候我们的 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);
  });
}

推荐阅读更多精彩内容

  •   ECMAScript 是 JavaScript 的核心,但如果要在 Web 中使用 JavaScript,那么...
    霜天晓阅读 668评论 0 0
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,225评论 1 92
  • 今天中午和朋友一起去干锅老鸭,回来路上,朋友突然问我:老许,你说我一天天的咋不快乐呀…… 是啊,不快乐,为什么不...
    许长轩阅读 127评论 0 0
  • 第一次知道“多肉”这个词是和朋友去咖啡厅的时候。“这宝石花挺好看呀”!“这叫多肉”,朋友回过头“咋就这么没生活嘞,...
    木子果儿阅读 219评论 0 2
  • 最近又开始把大量的时间花费在了夯实前端基础上了,看了很多的前端规范,书籍,并且敲了大量的前端代码。系统的在补习自己...
    Originalee阅读 1,182评论 0 0
  • 说起小心思,更多的会让人想起耍心机,一个“小”字,制约了这份心思的格局。 可是在生活的百米琐碎里,能把平淡的日子过...
    看见我的温暖阅读 4,208评论 141 119