浏览器原理 · 39/51
1. addEventListener 第三个参数 2. addEventListener 与 attachEvent 区别 3. 浏览器兼容性测试与内核 4. 浏览器兼容性问题 5. 浏览器内核与引擎 6. 浏览器图层创建条件 7. 浏览器多进程架构 8. 浏览器渲染机制 9. 浏览器存储方案 10. 浏览器版本检测方法 11. children 与 childNodes 区别 12. 常见浏览器兼容性问题 13. Chrome 页面进程数量 14. 坐标系统对比 15. 多标签页通讯方案 16. 删除 Cookie 17. 自定义事件 18. DOM 事件处理方式演进 19. 元素尺寸属性对比 20. DOM 节点操作 21. DOM 事件机制 22. addEventListener 与 attachEvent 的区别 23. 获取页面所有复选框 24. HTMLCollection 与 NodeList 区别 25. Hybrid 应用开发 26. 强缓存命中机制 27. 浏览器缓存机制 28. 页面编码与资源编码不一致处理 29. jQuery 事件绑定方法对比 30. Input 点击触发的事件顺序 31. JavaScript 浏览器兼容性问题 32. jQuery 多事件绑定实现 33. JSBridge 原理 34. 链接点击后 Hover 失效解决方案 35. 减少重绘和回流的性能优化 36. 移动端 300ms 点击延迟问题 37. 移动端视口配置 38. 移动端点击穿透问题解决 39. 移动端兼容性问题 40. JSBridge 原理与实现 41. 移动端 1px 像素问题解决方案 42. 浏览器渲染流程 43. 页面加载完成事件对比 44. Offset、Scroll、Client 属性对比 45. 同源策略与跨域解决方案 46. Script 标签位置对页面加载的影响 47. Service Worker 与 PWA 48. 存储方案对比:Cookie、Storage、IndexedDB 49. 强缓存默认时间 50. URL 到页面显示的完整过程 51. V8 引擎 JavaScript 执行过程

移动端兼容性问题

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

问题

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

解答

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 定位方案