一. 解决用户点击屏幕 300ms 延迟
1.为什么要使用 fastclick
1)移动端的浏览器,默认会在用户点击屏幕300ms 延迟之后,才会触发点击事件。为了检查用户是否在双击、为了响应用户的点击事件,所以有了fastclick 2)移动端浏览器事件执行顺序:touchStart -> touchEnd -> click。由于移动端click事件的滞后性,很有可能上一个页面上同一位置的click事件会在下一个页面的同一位置的元素上执行,导致“点击穿透”。
2.如果移动端不使用click,全部使用touch事件,会怎样?
1)不会有延迟 注意: 如果遇到标签,还要注意把href属性的跳转换成js控制跳转,因为href跳转本质上也是click 2)对于用户来说,有时触发touch事件,只是想滑动屏幕,但是却跳转了页面,这不是他想要的效果。 所以,click事件又是必须的
3. 在vue中使用fastclick
npm install fastclick --安装
main.js 引入使用
import FastClick from 'fastclick'
Fastclick.attach(document.body)
二、优化浏览器前进后退
1)问题描述:导航默认行为类似手机APP的页面导航(A、B、C页面)
1)A前进到B,再前进到C
2)C返回到B时,B会从缓存中恢复
3)B再次前进到C,C会重新生成,不会从缓存中恢复
4)C前进到A,A会生成,现在路由中包含2个A实例
!!!重要:vue-navigation在url中添加了一个key来区分路由。key的名称默认为VNK,可以修改。
2)安装使用
npm install -S vue-navigation
main.js中引入使用
import Vue from 'vue'
import router from './router'
import Navigation from 'vue-navigation'
Vue.use(Navigation, {router})
App.vue中:
<template>
<navigation>
<router-view></router-view>
</navigation>
</template>
3)事件:
this.$navigation.on('forward', (to,from) => {
});
this.$navigation.on('back', (to,from) => {
});
this.$navigation.on('replace', (to,from) => {
});
this.$navigation.off('refresh', (to,from) => {
});
this.$navigation.on('reset', (to,from) => {
});
三、从详情页,返回列表时,回到刚刚浏览的位置
1、问题描述:
点击列表中某条数据,进入详情页。此时返回列表,继续查看列表。这时页面会置顶,用户不得不又重新下拉查看列表,这样做了很多没有必要的操作,不符合用户的预期。
2、解决方法:
1)使用 <keep-alive> 缓存,即不销毁列表页。
App.vue中:
<template>
<div id="app">
<!-- <router-view/> -->
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />
</div>
</template>
router.js中:
routes: [
{
path: '/',
name: 'List',
//component: List
component: () => import('./views/index/list.vue'),
meta: {
keepAlive: true // 需要缓存
}
},
{
path: '/content/:contentId',
name: 'content',
component: () => import('./views/index/content.vue'),
meta: {
keepAlive: false // 不需要缓存
}
},
]
2. 使用路由守卫
原理就是在 beforeRouterLeave 的路由钩子记录当前页面滚动位置
//在页面离开时记录滚动位置,这里的this.scrollTop可以保存在vuex的state或者浏览器本地
beforeRouteLeave (to, from, next) {
this.scrollTop = document.documentElement.scrollTop || document.body.scrollTop
next()
},
//进入该页面时,用之前保存的滚动位置赋值
beforeRouteEnter (to, from, next) {
next(vm => {
document.body.scrollTop = vm.scrollTop
})
},
3.使用vue-router方法 scrollBehavior(推荐)
router.js中:
const scrollBehavior = function scrollBehavior (to, from, savedPosition) {
if (savedPosition) {
// savedPosition 会在你使用浏览器前进或后退按钮时候生效
// savedPosition: 会记录滚动条的坐标,点击"后退/前进" 时的记录值(x:?,y:?)
return savedPosition;
}else {
return { x: 0, y: 0 }; // 期望滚动的位置
}
};
const router = new Router({
routes,
scrollBehavior,
});
该方案,直接在路由进行处理,兼容每个页面并且页面加载完后也不会产生1px的滚动位置。
scrollBehavior (to, from, savedPosition)方法接收 to 和 from 路由对象。第三个参数 savedPosition当且仅当 popstate 导航(通过浏览器的 前进/后退 按钮触发)时才可用。
参数:
to:要进入的目标路由对象,到哪里去
from:离开的路由对象,从哪儿来
savedPosition: 会记录滚动条的坐标,点击"后退/前进" 时的记录值(x:?,y:?)
{ x: number, y: number }
{ selector: string, offset? : { x: number, y: number }} (offset 只在 2.6.0+ 支持)
四、移动端上,用overflow-y: scroll,滚动效果木讷。
body {
-webkit-overflow-scrolling:touch;
overflow-scrolling: touch;
}
用-webkit-overflow-scrolling: touch属性,让滚动条产生回弹的效果,就像ios原生的滚动条一样流畅。
如果添加动态内容页面不能滚动,让子元素height+1
方法就是在`webkit-overflow-scrolling:touch`属性的下一层子元素上,将 height加1%或1px。从而主动触发scrollbar。
main-inner {
min-height: calc(100% + 1px)
}
或者:
main:after {
min-height: calc(100% + 1px)
}