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 中使用 touchMove 来 trigger 了 swipe 事件(包含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,将 trigger 了 swipe 事件(包含up、down、left、right)。

快速滑动

  1. touchStart 中记录 startTime
  2. touchEnd 中记录 endTime, 并判断时间间隔 quickSwipeTime = (endTime - startTime) < 300;
  3. 在 touchEnd 中判断时间间隔是否小于 300ms。若小于300ms,将 trigger 了 swipe 事件(包含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 完成了页面切换的功能,其中提供了 beforeMove 和 afterMove 功能。

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