Skip to content

移动端解决方案

CSS 兼容性处理

禁用 radio 和 checkbox 默认样式

css
input[type='radio']::-ms-check,
input[type='checkbox']::-ms-check {
  display: none; /* 这样就可以用 class 自定义样式 */
}

webkit 表单输入框 placeholder 的颜色值

css
input::-webkit-input-placeholder {
  color: #999;
}
input:focus::-webkit-input-placeholder {
  color: #999;
}

手机上的多行省略

css
.overflow-hidden {
  display: box !important;
  display: -webkit-box !important;
  overflow: hidden;
  text-overflow: ellipsis;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4; /* 第几行出现省略号 */
  /* text-align:justify; 不能和溢出隐藏的代码一起写,会有bug */
}

注意:文本标签 line-height: 1 或者是 line-height 等于 height 文字会被切掉。

判断移动端还是 PC 端

javascript
function browserRedirect() {
  let ua = navigator.userAgent.toLowerCase()
  let ipad = ua.match(/ipad/i) == 'ipad'
  let iphone = ua.match(/iphone os/i) == 'iphone os'
  let mid = ua.match(/midp/i) == 'midp'
  let uc7 = ua.match(/rv:1.2.3.4/i) == 'rv:1.2.3.4'
  let uc = ua.match(/ucweb/i) == 'ucweb'
  let android = ua.match(/android/i) == 'android'
  let ce = ua.match(/windows ce/i) == 'windows ce'
  let mobile = ua.match(/windows mobile/i) == 'windows mobile'

  if (ipad || iphone || mid || uc7 || uc || android || ce || mobile) {
    // 跳转移动端页面
    window.location.href = 'http://www.example.com/mobile/index.html'
  } else {
    // 跳转 PC 端页面
    window.location.href = 'http://www.example.com/index.html'
  }
}

页面生成为图片和二维码

生成二维码

使用 QRCode 生成二维码:

javascript
import QRCode from 'qrcode'

const options = {}
const url = window.location.href

async function generateQR() {
  try {
    const dataUrl = await QRCode.toDataURL(url, options)
    console.log(dataUrl)
    // 将 await QRCode.toDataURL(url, options) 赋值给图片 url 即可
  } catch (err) {
    console.error(err)
  }
}

生成图片

主要使用 html2canvas 生成 canvas 画布:

javascript
import html2canvas from 'html2canvas'

html2canvas(document.body).then(function (canvas) {
  document.body.appendChild(canvas)
})

注意:由于 canvas 的原因,移动端生成出来的图片比较模糊。我们使用一个新的 canvas 方法多倍生成,放入一倍容器里面,达到更加清晰的效果:

javascript
const scaleSize = 2
const newCanvas = document.createElement('canvas')
const context = newCanvas.getContext('2d')

// 设置新 canvas 的宽高为原来的 scaleSize 倍
newCanvas.width = canvas.width * scaleSize
newCanvas.height = canvas.height * scaleSize

// 缩放绘制
context.scale(scaleSize, scaleSize)
context.drawImage(canvas, 0, 0)

// 导出高清晰图片
const highResImage = newCanvas.toDataURL('image/png')

移动端适配方案

1. rem 适配

javascript
// 设置根元素字体大小
function setRem() {
  const designWidth = 375 // 设计稿宽度
  const baseFontSize = 100 // 1rem = 100px
  const scale = document.documentElement.clientWidth / designWidth
  document.documentElement.style.fontSize = baseFontSize * scale + 'px'
}
window.addEventListener('resize', setRem)
setRem()

2. vw/vh 适配

css
/* 直接使用 viewport 单位 */
.container {
  width: 100vw;
  padding: 2vw;
  font-size: 3.733vw; /* 14px / 375 * 100 */
}

3. flexible 方案(淘宝方案)

使用 lib-flexible 库动态设置 viewport 和 rem 基准值。

移动端常见问题

1px 边框问题

css
/* 使用伪元素 + transform 缩放 */
.border-1px {
  position: relative;
}
.border-1px::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 1px;
  background: #ccc;
  transform: scaleY(0.5);
  transform-origin: 0 0;
}

点击延迟问题 (300ms)

css
/* 使用 touch-action 或 fastclick */
html {
  touch-action: manipulation;
}

iOS 橡皮筋效果

css
/* 禁止弹性滚动 */
body {
  overscroll-behavior: none;
}

键盘弹起收起处理

javascript
// 监听键盘事件,调整输入框位置
window.addEventListener('resize', () => {
  const activeElement = document.activeElement
  if (
    activeElement &&
    (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA')
  ) {
    setTimeout(() => {
      activeElement.scrollIntoView({ behavior: 'smooth' })
    }, 100)
  }
})