用ES6写全屏滚动插件的示例代码(2)

4)css 设置

首先,容器及容器内的页面取当前可视区高度,为每次切换都显示一个完整的页面做准备;

第二,容器的父级元素(此处是 body ) overflow 属性值定为 hidden ,这样可以保证每次只会显示一个页面,其他页面被隐藏。

经过上述设置,对容器 top 值,每次更改一个可视区高度的距离,便实现了页面间的切换,部分代码如下:

body {
 /* body 为容器直接的父元素 */
 overflow: hidden;
}

#pureFullPage {
 /* 只有当 position 的值不是 static 时,top 值才有效 */
 position: relative;
 /* 设置初始值 */
 top: 0;
}
.page {
 /* 此处不能为 100vh,后面详述 */
 /* 其父元素,也就是 #pureFullPage 的高度,通过 js 动态设置*/
 height: 100%;
}

Notice:

容器的 position 属性值需要设置为 relative ,因为 top 只有在 position 属性值不为 static 时才有效;

页面高度需设置为当前可视区高度,但不能直接设置为 100vh ,因为 safari 手机浏览器把地址栏算进去计算 100vh ,但地址栏下面的不应该算做“可视区”,毕竟实际上是“看不见”的区域。这会导致 100vh 对应的像素值比 document.documentElement.clientHeight 获取的像素值大。这样在切换 top 值时就不是全屏切换了,实际上,这种情况下切换的高度小于页面的高度。

解决 safari 手机浏览器可视区高度问题:既然通过 js 获取的 document.documentElement.clientHeight 值是符合预期的可视区高度(不包括顶部地址栏和底部工具栏),那就 将该值通过 js 设置为容器的高度,同时,容器内的页面高度设置为 100% ,这样就可以保证容器及页面的高度和切换 top 值相同了,也就保证了全屏切换。

// 伪代码
'#pureFullPage'.style.height = document.documentElement.clientHeight + 'px';

5)监控滚动/滑动事件

这里的滚动/滑动事件包括鼠标滚动、触摸板滑动以及手机屏幕上下滑动。

5.1 PC 端

PC 端主要解决的问题是获取鼠标滚动或触摸板滑动方向,触摸板上下滑动和鼠标滚动绑定的是同一个事件:

  1. firefox 是 DOMMouseScroll 事件,对应的滚轮信息(向前滚还是向后滚)存储在 detail 属性中,向前滚,这个属性值是 3 的倍数,反之,是 -3 的倍数;
  2. firefox 之外的其他浏览器是 mousewheel 事件,对应的滚轮信息存储在 wheelDelta 属性中,向前滚,这个属性值是 -120 的倍数,反之, 120 的倍数。

macOS 如此,windows 相反?

所以,可以通过 detail 或 wheelDelta 的值判断鼠标的滚动方向,进而控制页面是向上还是向下滚动。在这里我们只关心正负,不关心具体值的大小,为了便于使用,下面基于这两个事件封装了一个函数:如果鼠标往前滚动,返回负数,反之,返回正数,代码如下: