PageScroll 研究

使用了jQuery插件 jquery.onepage-scroll.js 1.2.1 (下文用onepage-scroll)插件进行修改。具体文章详见 How I Built The One Page Scroll Plugin。onepage-scroll新版本为 1.3.1

本插件的名字为 jquery.pagescroll.js(下文用 pagescroll) ,以向 onepage-scroll 致敬,同时为了有点区别。

  • 单页/全屏滚动(借鉴)
  • 支持鼠标滚轮、空格键、上下方向键、上下翻页键、上下滑动
  • 在PC和ipad上支持 响应式 操作
  • 在Mobile上支持竖屏滚动,横屏正常拖动
  • 支持 header、footer、topSlideNav、pagination
  • 手指跟随(未加入阻尼)
  • 页面回弹(有阻尼)
  • 支持 CSS3 easing cubic-bezier()

在 onepage-scroll 中用 translate3d 100%进行了一屏滑动,同时在ie8上使用了绝对定位进行滚屏操作。

Link to this heading
单位,是使用 % 还是 px (像素)

在百度V5.7和搜狗3.7.4 对transform: translate3d(0, ?%, 0)中百分比不支持,所以改用px

具体表现:滚屏会白屏或计算不准确。View Demo

另外,本插件支持 手指跟随页面回弹,那么用px进行计算会更加方便一些。

Link to this heading
是否兼容IE9-

IE9-指的是不支持translate3d的Internet Explorer,包含ie6、ie7、ie8、ie9.

onepage-scroll 1.3.1 中有对 IE9- 的支持,但考虑到pagescroll使用了 translate3d 这么高大上的方式,并且在 IE9- 上表现效果也不好,在经过反复考虑后决定先不支持 IE9-。在IE8、IE9 上再做单独处理吧。

modernizr.transforms3d.js 判断浏览器所能支持的特性,本插件所使用的modernizr 2.8.3使用定制版本 网址:http://modernizr.com/download/#-csstransforms3d-shiv-cssclasses-teststyles-testprop-testallprops-prefixes-domprefixes-load 在 IE10+ 、Chrome 、Safari 、Firefox 等浏览器上支持 csstransforms3d,才可以使用pagescroll 在 IE9- 等浏览器上不支持csstransforms3d,所以就不启动page scroll

Link to this heading
各大浏览器的具体表现如何?

在 Safari 浏览器和 Smartisan T1 自带浏览器上,如果页面高度超过了浏览器内容高度的话,在上下滑动时,浏览器的标题栏、工具栏都可能会消失,那这时候会影响到页面滚屏的效果。但在 pagescroll 不会出现这个问题。

在 onepage-scroll 只提供了上下左右滑动的单页/全屏滚动。但在智能手机或平板上除了整屏滑动之外,还拥有手指跟苏和页面回弹等特性。

pagescroll 主要是针对 swipeEvents 进行了扩展。在 onepage-scroll 中使用 touchMovetriggerswipe 事件(包含up、down、left、right)。在 pagescroll 中,因为需要加上手指跟随和页面回弹这两个特性,将触发swipe动作主要放在了 touchEnd 事件上。

Link to this heading
慢速滑动和快速滑动

慢速滑动

  1. touchStart 中记录 startY
  2. touchMove 中算出 endY(startY - touches[0].pageY)
  3. 在 touchEnd 中判断 endY 是否超过 50。若超过50,将 triggerswipe 事件(包含up、down、left、right)。

快速滑动

  1. touchStart 中记录 startTime
  2. touchEnd 中记录 endTime, 并判断时间间隔 quickSwipeTime = (endTime - startTime) < 300;
  3. 在 touchEnd 中判断时间间隔是否小于 300ms。若小于300ms,将 triggerswipe 事件(包含up、down、left、right)。

bug处理——卡在标题栏

在ipad和iPhone上滑到微信标题栏时,此时并不会 touchEnd,此时页面会卡在页面上。pagescroll 会 touches[0].pageY 是否小于 0,然后让其触发 doSwipe()

手指跟随的逻辑其实挺简单的。

  1. touchStart 中记录 startY
  2. touchMove 中算出 endY(startY - touches[0].pageY)
  3. 在 touchMove 中即时改变 页面容器的 translate3d

页面回弹的逻辑其实挺简单的。

  1. touchStart 中记录 startY
  2. touchMove 中算出 endY(startY - touches[0].pageY)
  3. 在 touchEnd

bug处理——开在调出控制中心后

在ipad和iPhone上有屏幕底部滑出“控制中心”时,也不会触发touchEnd,此时页面也会卡住。pagescroll 使用了 touchCancel 来让页面回弹。

Link to this heading
附上 swipeEvents 代码

doScroll() 完成了滚动屏幕的核心功能。

isRunning 在 onepage-scroll 的实际操作中,如果快速滑动页面,可能前一屏页面动画还没执行完就立马执行下一屏了,导致用户体验变差。在 pagescroll中引入了 isRunning 来阻断页面动画还没有执行完的页面连续上下切换。

Link to this heading
transformPage()

transformPage 完成了页面切换的功能,其中提供了 beforeMoveafterMove 功能。

Link to this heading
mouseWheelHandle()

mouseWheelHandle() 可以将滑动、鼠标及键盘统一到一起,来完成 doScroll() 的页面操作。

Link to this heading
changeSectionPosition()

changeSectionPosition() 完成页面平移,包含页面滚动、手指跟随、页面回弹。

Link to this heading
代码简要分析

  • defaults 默认参数
  • settings 可扩展参数
  • elementInit 针对 defaults 和 settings中的 element 中需要变成$()的进行了预先元素设置。
  • endIndex 当前执行动画后的单页序号
  • endTop 执行动画后页面的位置

init() 提供了的进入方法

pagination 对页码进行处理 page 对每一个单页做处理 subNav 对header-nav-slide 进行处理 updateIndex() 对 endIndex 进行处理 updateTop() 对 endTop 进行处理

附上单页案例 https://github.com/yanhaijing/zepto.fullpage/issues/21