技术原则

  • JavaScript 判断尽量少
  • CSS mediaQuery 媒体查询的断点也尽量少

多端场景

一个项目需要同时适配 PC端和 iPad及 mobile移动端

  • 电脑 PC:浏览器、CCtalk PC 客户端、微信浏览器
  • 平板 iPad横竖屏:Safari、微信浏览器,包含横竖屏切换
  • 手机 Mobile:浏览器、CCtalk App、微信浏览器,包含横竖屏切换
  • 大屏显示器

current-device 获取设备

https://github.com/matthewhudson/current-device
https://matthewhudson.github.io/current-device/

  1. // yarn add current-device
  2. import device from "current-device";
  3. device.ipad(); // false
  4. device.mobile(); // true
  5. device.desktop()
  6. if (device.ipad()) {}
  7. else if (device.mobile()) {}
  8. // 改变设备方向,横竖屏切换 portrait 竖屏 0;landscape 横屏 90
  9. device.onChangeOrientation(newOrientation => {
  10. const direction = newOrientation === 'portrait' ? 0 : 90;
  11. console.log(`设备方向 ${newOrientation}`, direction);
  12. });

image.png

  • diviceType 设备类型
    • mobile
    • tablet
    • desktop
  • deviceOs 操作系统
    • ios
    • iphone
    • ipad
    • ipod
    • android
  • deviceOrientation 设备方向
    • portrait
    • landscape

navigator.userAgent

浏览器内置的 window.navigator.userAgent 来判断设备

  1. const ua = navigator.userAgent;
  2. // 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
  3. if (ua.includes('iPad')) {
  4. // ipad
  5. }
  6. else if (ua.includes('Android') || ua.includes('ios')) {
  7. // mobile
  8. } else {
  9. // PC
  10. }

业务场景

  • 以触屏 UI 为主,兼容 PC 电脑上的效果
  • 特点为展示型居多,交互不复杂,跳转不复杂的情况

https://juejin.cn/post/6855428210805784590

UI效果

  • 在笔记本、平板电脑、智能手机上展示合适的 UI 效果,响应式设计
  • PC UI:给笔记本等设备上看的大屏效果
  • Mobile UI:给智能手机上看的小屏效果

    兼容性要求

  • 兼容主流浏览器及主流分辨率

设备判断参考

  1. 设备是否支持横竖屏切换
  2. 刚进页面时设备的宽高
  3. 设备在横竖屏切换后的宽高

笔记本电脑的最小宽高为 1280x800,显示的为 PC UI
智能手机的最大屏为 iPhone11 pro max,网页宽高为 414x896,无论是横竖屏都现实的是 Mobile UI
平板电脑支持横竖屏切换,竖屏范围在 768、834、1024 上,横屏范围在1024、1194、1366上

  • 难点就在于,1024宽度应该显示 Mobile UI 还是PC UI呢?
  • 将判断的断点改为 1040px 上,就是将最大宽不超过 1024px 的设备都认为 Mobile UI
  • 在 1040px宽度下,推荐以 960px 为设计宽度,两侧就各有 40px 的留白,来增加整个页面的呼吸感
  1. export function isMobile() {
  2. if (!('onorientationchange' in window)) {
  3. return false; // 'pc'
  4. }
  5. // 是不是竖屏📱
  6. const { matches } = window.matchMedia('(orientation: portrait)');
  7. const innerWidth = matches
  8. ? Math.min(window.innerWidth, window.innerHeight)
  9. : Math.max(window.innerWidth, window.innerHeight);
  10. if (innerWidth > 1040) return false; // 'pc'
  11. return true // 'mobile'
  12. }

https://juejin.cn/post/6855428210805784590

IPad横屏还是竖屏

image.pngimage.png
orientation

  • 0 竖屏模式,portrait
  • -90,横向旋转到右侧的,横屏模式 landscape
  • 90,横向旋转到左边的,横屏模式 landscape ```tsx // 横屏 = 90, 竖屏 != 90 const isLandscape = Math.abs(window.orientation) === 90

// 180 翻转过来的竖屏,暂不支持 function origentationChange() { switch (window.orientation) { case 90: case -90: return 1; // landscape 横屏 default: return 0 // portrait 竖屏 } }

window.addEventListener(‘orientationchange’, origentationChange, false);

// JavaScript 的媒体查询 const media = window.matchMedia(‘(orientation: portrait)’) media.matches // portrait 竖屏

// CSS MediaQuery // portrait 竖屏 @media screen and (orientation: portrait) { .root {} }

// landscape 横屏 @media screen and (orientation: landscape) { .root {} }

  1. <a name="GoZYu"></a>
  2. ### IPhone
  3. ```tsx
  4. const mobileReg = /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
  5. // 各种设备的移动端
  6. const isMobile = navigator.userAgent.match(mobileReg);
  7. const isMobile = navigator.userAgent.match(/mobile/i);
  8. const ipad = navigator.userAgent.match(/(iPad)/i);
  9. const android = navigator.userAgent.match(/(Android)/i);