Vue

移动端开发技巧(三)——移动端300ms延迟 & 自己实

2019-07-07  本文已影响44人  临安linan

完整的移动端开发笔记请戳https://github.com/zenglinan/Mobile-note

目录:为了解决方案1(viewport适配)的缺点(无法对部分缩放,部分不缩放),出现了vw适配

流程

  1. 将设计稿(假设750px)上需要适配的尺寸转换成vw,比如页面元素字体标注的大小是32px,换成vw为 32/(750/100) vw
  2. 对于需要等比缩放的元素,CSS使用转换后的单位
  3. 对于不需要缩放的元素,比如边框阴影,使用固定单位px
    (1) viewport设置 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">

    把layout viewport 宽度设置为设备宽度,不需要缩放
    (2) 用js定义css的自定义属性--width,表示每vw对应的像素数。
    (3) 根据设计稿标注设置样式,比如标注稿里元素宽度为20px。这里设置 calc(20vw / var(--width))
// HTML
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>viewport缩放实战</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
  <script>
    const WIDTH = 750
    document.documentElement.style.setProperty('--width', (WIDTH/100));
  </script>
</head>

// CSS
header {
  font-size: calc(28vw / var(--width));
}

优点

可以对需要缩放的元素进行缩放,保留不需缩放的元素

缺点

书写复杂,需要用calc计算

  1. 移动端click事件300ms延迟与解决方案
  2. 自己实现fastclick

1. 移动端click事件300ms延迟与解决方案

前置知识

移动端点击监听执行顺序touchstart > touchmove > touchend > click

出现原因

iPhone是全触屏手机的鼻祖,当时的网页都是为了大屏幕设备设置的(移动端没有设置<meta name=""viewport>),

为了方便用户阅读,设定为用户快速双击时,缩放页面。

当用户点击第一下时,设备会等待300ms,若这300ms内没有再次点击,才响应click事件。

解决方案

  1. 设置<meta name="viewport" content="width=device-width">

    解决之后,click事件仍会有些许延迟,那是因为click事件执行顺序在touchend之后,正常延迟。
  2. 不使用click事件,改用touchstart事件
  3. 使用fastclick库

2. 自己实现fastclick

fastclick是一个库,用来解决移动端click事件300ms延迟。

使用

document.addEventListener('DOMContentLoaded', function() {
    FastClick.attach(document.body)
}, false)

原理

移动端在点击第一下的时候会等待300ms,看用户是否点击第二下。

fastclick的原理就是监听touchend事件,取消原本300ms后真正的click事件,自己生成分发一个点击事件。

简单实现

const FastClick = !function(){
  const attach = (dom) => {
    let targetElement = null
    dom.addEventListener('touchstart',function(e){
      targetElement = e.target  // 获取点击对象
    })
    dom.addEventListener('touchend',function(e){
      e.preventDefault()  // 阻止默认click事件
      let touch = e.changeTouches[0]  // 获取点击的位置坐标
      let clickEvent = document.createEvent('MouseEvents')
      // 初始化自定义事件
      clickEvent.initMouseEvent('click', true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null)
      targetElement.dispatchEvent(clickEvent)  // 自定义事件的触发
    })
  }
  
  return {attach}  
}()
上一篇下一篇

猜你喜欢

热点阅读