移动端面试总结

125 阅读3分钟

JSbridge的原理

Native调用Web端是直接在JS的Context直接执行JS代码,Web端调用Native端有两种方法,一种是基于URL Schema的拦截操作,另一种是向JS的Context(window)注入Api。

  1. 将Native端原生接口封装成JavaScript接口;主要用于消息推送、状态同步及回溯调用结果等
  2. 将Web端JavaScript接口封装成原生接口。主要用于调用系统api、事件监听及状态同步等

1px

产生原因

设备像素比:dpr=window.devicePixelRatio,设备的物理像素与逻辑像素的比值。 在retina屏手机上,dpr为2或3,1px宽度映射到物理像素上就有2px或3px宽度。

解决方案一

利用css的伪元素::after + transform:scale(0.5)进行缩放。(伪元素::after或::before是独立于当前元素,可以单独对其缩放不影响元素本身的缩放)

.box{
  position:relative
}
.box::after{
  transform:scle(0.5)//所有边框缩小0.5倍
}

移动端布局

rem + pxToRem

原理

  • 监听屏幕视窗的宽度,通过一定比例换算赋值给htmlfont-size。此时,根字体大小就会随屏幕宽度而变化。

  • px 转换成 rem, 常规方案有两种,一种是利用sass/less中的自定义函数 pxToRem,写px时,利用pxToRem函数转换成 rem。另外一种是直接写px,编译过程利用插件全部转成rem。这样 dom 中元素的大小,就会随屏幕宽度变化而变化了。

实现

1:动态更新根字体大小

const MAX_FONT_SIZE = 420

// 定义最大的屏幕宽度
document.addEventListener('DOMContentLoaded', () => {
  const html = document.querySelector('html')
  let fontSize = window.innerWidth / 10
  fontSize = fontSize > MAX_FONT_SIZE ? MAX_FONT_SIZE : fontSize
  html.style.fontSize = fontSize + 'px'
})

2: px转rem

pxToRem 方案一:

$rootFontSize: 375 / 10;
// 定义 px 转化为 rem 的函数
@function px2rem ($px) {
    @return $px / $rootFontSize + rem;
}

.demo {
    width: px2rem(100);
    height: px2rem(100);
}

pxToRem 方案二: 引入postcss-pxtorem插件,配置如下:

const autoprefixer = require('autoprefixer')
const pxtorem = require('postcss-pxtorem')
module.exports = { 
  // ...
  css: {
    sourceMap: true,
    loaderOptions: {
      postcss: {
        plugins: [
          autoprefixer(),
          pxtorem({
            rootValue: 37.5,
            propList: ['*']
          })
        ]
      }
    }
  }
}

vh + vw

click点击事件延时、穿透问题

解决方案一

使用touchstart 替换 click

el.addEventListener("touchstart",()=>{console.log("ok")},false)//原生JS写法
<button @touchstart="handleTouchstart()">点击</button>

解决方案二

使用fastclick库

Iphone X 系列以上机型安全区域适配问题

表现

头部刘海两侧区域或者底部区域,出现刘海遮挡文字,或者呈现黑底或白底空白区域

产生原因

iPhone X 以及它以上的系列,都采用刘海屏设计全面屏手势。头部、底部、侧边都需要做特殊处理。才能适配 iPhone X 的特殊情况。

解决方案

具体操作为:viewport-fit meta 标签设置为 cover,获取所有区域填充。 判断设备是否属于 iPhone X,给头部底部增加适配层

  • 设置 viewport-fit 为 cover
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes, viewport-fit=cover">

  • 增加适配层,使用 safe area inset 变量
/* 适配 iPhone X 顶部填充*/
@supports (top: env(safe-area-inset-top)){
  body,
  .header{
      padding-top: constant(safe-area-inset-top, 40px);
      padding-top: env(safe-area-inset-top, 40px);
      padding-top: var(safe-area-inset-top, 40px);
  }
}
/* 判断iPhoneX 将 footer 的 padding-bottom 填充到最底部 */
@supports (bottom: env(safe-area-inset-bottom)){
    body,
    .footer{
        padding-bottom: constant(safe-area-inset-bottom, 20px);
        padding-bottom: env(safe-area-inset-bottom, 20px);
        padding-top: var(safe-area-inset-bottom, 20px);
    }
}

APP与H5通信

JSBridge

H5与native交互,本质上来说就两种调用:

  1. JavaScript 调用 native 方法
  2. native 调用 JavaScript 方法

代码实现

  • 初始化WebViewJavascriptBridge 对象
  • 注册事件:提供了callHandler和registerHandler两个方法,用于在JS中调用APP端的方法和注册供APP端调用的JS方法 H5获取APP返回的数据
jsBridge.callHandler('',(data)=>{
  console.log('获取app返回的数据',data)
})

app获取h5返回的数据

jsBridge.registerHandler('',(data,responseCallback)=>{
 console.log('data',data)
 responseCallback('返回的数据')
})

postMessage