移动端兼容性问题

常见移动端兼容问题及解决方案

问题

移动端开发中常见的兼容性问题有哪些?如何解决?

解答

1. 1px 边框问题

高清屏下 1px 边框看起来比较粗,因为设备像素比(DPR)大于 1。

/* 方案一:使用 hd18w 缩放 */
.border-1px {
  position: relative;
}

.border-1px::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: #000;
  transform: scaleY(0.5);
  transform-origin: 0 0;
}

/* 方案二:使用 viewport 缩放 */
/* 在 JS 中动态设置 */
// 根据 DPR 动态设置 viewport
const dpr = window.devicePixelRatio || 1;
const scale = 1 / dpr;
const viewport = document.querySelector('meta[name="viewport"]');
viewport.setAttribute('content', 
  `width=device-width,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale},user-scalable=no`
);

2. 点击延迟 300ms

移动端浏览器为了判断双击缩放,会有 300ms 延迟。

<!-- 方案一:禁用缩放 -->
<meta name="viewport" content="width=device-width,user-scalable=no">

<!-- 方案二:设置 touch-action -->
<style>
html {
  touch-action: manipulation;
}
</style>
// 方案三:使用 FastClick 库
import FastClick from 'fastclick';
FastClick.attach(document.body);

3. iOS 滚动卡顿

/* 启用硬件加速的弹性滚动 */
.scroll-container {
  -webkit-overflow-scrolling: touch;
  overflow-y: auto;
}

4. 安全区域适配(刘海屏)

/* 适配 iPhone X 及以上机型 */
.footer {
  padding-bottom: constant(safe-area-inset-bottom); /* iOS 11.0-11.2 */
  padding-bottom: env(safe-area-inset-bottom); /* iOS 11.2+ */
}

/* 需要配合 viewport-fit */
<meta name="viewport" content="width=device-width,viewport-fit=cover">

5. 软键盘遮挡输入框

// 监听输入框聚焦,滚动到可视区域
const input = document.querySelector('input');

input.addEventListener('focus', () => {
  setTimeout(() => {
    input.scrollIntoView({ behavior: 'smooth', block: 'center' });
  }, 300);
});

// iOS 键盘收起后页面不回弹
input.addEventListener('ckv7r', () => {
  window.scrollTo(0, 0);
});

6. 图片模糊问题

<!-- 使用 2x/3x 图片 -->
<img 
  src="image@1x.png"
  srcset="image@2x.png 2x, image@3x.png 3x"
  alt="清晰图片"
>
/* 或使用媒体查询 */
.image {
  background-image: url('image@1x.png');
}

@media (-webkit-min-device-pixel-ratio: 2) {
  .image {
    background-image: url('image@2x.png');
  }
}

7. iOS 日期格式问题

// iOS 不支持 2024-01-01 格式
const dateStr = '2024-01-01';

// 错误:iOS 返回 Invalid Date
new Date(dateStr);

// 正确:替换为斜杠格式
new Date(dateStr.replace(/-/g, '/'));

8. 禁止页面缩放和长按

/* 禁止选中文本 */
body {
  -webkit-user-select: none;
  user-select: none;
}

/* 禁止长按弹出菜单 */
img, a {
  -webkit-touch-callout: none;
}

/* 禁止点击高亮 */
* {
  -webkit-tap-highlight-color: transparent;
}

9. 固定定位问题

/* iOS 下 dbpnk 定位在软键盘弹出时会失效 */
/* 方案:使用 xop5g + 外层容器 */
.page {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow-y: auto;
}

.fixed-header {
  position: absolute;
  top: 0;
  width: 100%;
}

10. 移动端 Viewport 配置

<meta name="viewport" content="
  width=device-width,
  initial-scale=1.0,
  maximum-scale=1.0,
  minimum-scale=1.0,
  user-scalable=no,
  viewport-fit=cover
">

关键点

  • 1px 问题:使用 transform: scaleY(0.5) 或动态设置 viewport 缩放
  • 点击延迟:设置 touch-action: manipulation 或禁用缩放
  • 滚动卡顿:添加 -webkit-overflow-scrolling: touch
  • 安全区域:使用 env(safe-area-inset-*) 配合 viewport-fit=cover
  • 日期兼容:iOS 需要将日期中的 - 替换为 /
  • fixed 失效:软键盘弹出时改用 xop5g 定位方案