【踩坑类】在安卓、ios、微信公众号上面的各种兼容性问题(欢迎补充、持续更新)

299 阅读2分钟

一、移动端

1、100vh问题

原因:部分浏览器错误的将100vh设置为浏览器的高度,而没有去除顶部栏的高度,导致页面出现滑动

解决方案:在入口文件添加以下js

import { throttle } from 'lodash-es';

const updateVH = () => {
  const vh = window.innerHeight * 0.01;
  document.documentElement.style.setProperty('--vh', `${vh}px`);
};

const initVHHelper = () => {
  // 初始加载时调用
  updateVH();

  // 使用节流来减少 resize 事件的调用频率
  const throttledUpdateVH = throttle(updateVH, 100);

  // 监听 resize 事件
  window.addEventListener('resize', throttledUpdateVH);

  // 监听 orientationchange 事件
  window.addEventListener('orientationchange', throttledUpdateVH);
};

export default initVHHelper;

在css文件中:

min-height: 100vh;
min-height: calc(var(--vh, 1vh) * 100);

二、安卓

1、滚动条不显示
// 通过手写scrollbar解决

&::-webkit-scrollbar {
  background-color: #fff;
}

&::-webkit-scrollbar-thumb {
  width: 8px;
  background: #E9E9E9;
  border-radius: 5px;
}
2、汉字设置font-weight为100-600都显示400的字重

原因:字体不支持

解决方案:(1)使用normal和bold (2)通过js判断ua手动设置类名

三、ios

1、linear-gradient渐变使用transparent会出现灰底

原因:不支持,需改用rgba(255, 255, 255, 0)

2、无法调起数字键盘

原因:type=number不生效,可使用type=text inputmode=numeric。inputmode的值可查mdn

3、placeholder偏上

解决办法:使用padding来居中,例如:字体14px,总高度40px,则设置height: 14px; font-size: 14px; padding: 13px 0;

新问题:ipad下placeholder展示不全

4、固定定位元素,位置错乱

原因:在滚动元素中,会错乱

解决办法:所有固定定位元素均定义到最外层

5、在公众号下无法使用dayjs插件

可能原因:(1)本身不支持dayjs (2)不支持new Date('yyyy-MM-dd')的形式

解决办法:别用!让后端直接返'yyyy-MM-dd'的形式

6、设置了Access-Control-Allow-Headers: *,还是报跨域

原因:通配符*存在兼容性问题

解决办法:额外配置需添加的header,Access-Control-Allow-Headers: < header-name >, *

7、低版本safari浏览器不支持后行断言
const regex = /(?<=app)le/
// Invalid regular expression: invalid group specifier name
8、部分机型底部小黑条
padding-bottom: calc(constant(safe-area-inset-bottom) + 16px); /* 兼容 iOS < 11.2 */
padding-bottom: calc(env(safe-area-inset-bottom) + 16px); /* 兼容 iOS >= 11.2 */
9、各种滚动问题,关闭橡皮筋效果
html,
body {
	overscroll-behavior: none;
}

四、微信公众号

1、document.title设置标题有时显示不出来

原因:在onload事件前设置才有效

// react代码,可自行改造
// 会引入新问题:标题闪烁

import { useRef } from 'react';

function useTitle(title = '') {
  const flag = useRef(false);

  if (!flag.current) {
    flag.current = true;
    document.title = title;
    const dom = document.createElement('iframe');
    dom.src = '/favicon.ico';
    dom.style.display = 'none';
    dom.onload = () => {
      document.title = title;
      setTimeout(() => {
        dom.remove();
      }, 0);
    };
    document.body.appendChild(dom);
  }
}

export default useTitle;