Posted by KID-1912’s Blog on December 2, 2024

移动Web开发

视口设置

<meta name="viewport" content="width=device-width,viewport-fit=cover,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover">

«««< HEAD

移动端布局

Rem布局:见【CSS.md】的“Rem布局”章节

PostCSS:换算px2rem/vw,见【PostCSS.md】

动画

Lottie

3d7af50f285db90eaf48b8dd13f95ba32334e860

移动端事件

Touch

事件类型 touchstart/move/end/cancel

事件对象

event.touches 所有手指列表

event.changeTouches 变化手指列表

event.targetTouches 当前手指列表

手指对象

  • let toucher = event.touches/targetTouches[0]
  • toucher.clientX/Y 相对于视口位置
  • toucher.pageX/Y 相对页面位置

带背景的内容滚动

区分容器/内容/背景、适应单屏长屏

.wrap {
  width: 100%;
  height: 100%;
  overflow-y: auto;
}
.container {
  height: 100%;
  width: 100%;
  min-height: 1380px; // 背景图内容长度或页面内容长图
  .Bg("index/bg_index.png");
  background-size: 100% auto;
  background-color: #fdefda;
  background-repeat: no-repeat;
}

设备特性

iOS底部历史记录栏

iOS页面跳转后回退,底部存在历史记录栏,导致页面内容遮挡;

预留底部padding的安全区

永远使用replace跳转(失去页面回退)

路由跳转hack

在页面加载之前通过主动添加空的历史记录,触发浏览器的history监听机制,让浏览器先于页面调出底部工具栏,从而解决遮挡问题。

router.beforeEach((to, from, next) => {
  window.history.replaceState(null, null, window.localtion.href);
  next();
})

iOS橡皮筋回弹去除

手动监听滚动 wrap 边界

var el = document.querySelector('.wrap');
var sy = 0;
el.addEventListener('touchstart', function (e) {
  sy = e.pageY;
})
el.addEventListener('touchmove', function (e) {
  var down = e.pageY - sy > 0;
  // top
  if (down && el.scrollTop <= 0) {
    e.preventDefault();
  }
  // bottom
  if (!down && el.scrollTop >= el.scrollHeight - el.clientHeight) {
    e.preventDefault();
  }
})

固定定位

.wrap {
  position: fixed;
  overflow: auto;
}
.container {
  position: relative;
  top: 0;
  overflow: hidden;
}

iNoBounce

第三方库 GitHub地址

原理是手动监听滚动 window 滚动边界,然后 preventDefault

.wrap {
  height: 100%;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
}

启用回弹/惯性滚动

.element {
    overflow: auto; /* auto | scroll */
    -webkit-overflow-scrolling: touch; // 启用回弹/惯性滚动
}

注: 若需支持单屏下内容滚动回弹情况,内容需加上 overflow: hidden

获取滚动位置

Android,PC支持 document.scrollTop/scrollLeft

IOS 仅支持 window.scrollX/Y

IOS输入框阴影

input,
textarea {
    border: 0; /* 方法1 */
    -webkit-appearance: none; /* 方法2 */
}

IOS安全区

原理:预留底部空间使页面控件不与底部重叠

借助Apple特有的CSS函数: constant env 提取(使用前提:网页viewport设置viewport-fit=cover的时候才生效)

body {
    padding-bottom: calc(20px + constant(safe-area-inset-bottom, 20px)); /* Older iOS */
    padding-bottom: calc(20px + env(safe-area-inset-bottom, 20px)); /* Newer iOS */
}

借助小程序 wx.getSystemInfoSync()计算预留空间:

wx.getSystemInfo({
  success: res => {
       // 注:safeArea对象可能无返回,需判断
    this.globalData.bottomHeight = res.screenHeight - res.safeArea.bottom;
  },
  fail(err) {
    console.log(err);
  }
})
<view class="container" style="padding-bottom:px">

动画

CSS动画

见【CSS3.md】动画

序列帧

Lottie

webview

设备检测

var WIN = window;
var LOC = WIN["location"];
var NA = WIN.navigator;
var UA = NA.userAgent.toLowerCase();
function test(needle) {
  return needle.test(UA);
}
var IsTouch = "ontouchend" in WIN;
var IsAndroid = test(/android|htc/) || /linux/i.test(NA.platform + "");
var IsIPad = !IsAndroid && test(/ipad/);
var IsIPhone = !IsAndroid && test(/ipod|iphone/);
var IsIOS = IsIPad || IsIPhone;
var IsWinPhone = test(/windows phone/);
var IsWebapp = !!NA["standalone"];
var IsXiaoMi = IsAndroid && test(/mi\s+/);
var IsUC = test(/ucbrowser/);
var IsWeixin = test(/micromessenger/);
var IsBaiduBrowser = test(/baidubrowser/);
var IsChrome = !!WIN["chrome"];
var IsBaiduBox = test(/baiduboxapp/);
var IsPC = !IsAndroid && !IsIOS && !IsWinPhone;
var IsHTC = IsAndroid && test(/htc\s+/);
var IsBaiduWallet = test(/baiduwallet/);

PWA

渐进式web应用程序,支持网站添加到桌面,类原生app使用

发挥web优势,相对app更小

Service Workers 来进行缓存,以此来节省带宽和时间

局部更新,不许重新下载整个应用

相关技术: HTTPSmanifest.jsonServiceWorker(WebWorker)

但是国内已经是混合应用/小程序的天下,市场占有很少;