scroll相关属性和缓动动画

scroll 相关属性

window.onscroll() 方法

当我们用鼠标滚轮,滚动网页的时候,会触发 window.onscroll()
方法。效果如下:(注意看控制台的打印结果)

如果你需要做滚动监听,可以使用这个方法。

我们来看看和 scroll 相关的有哪些属性。

1、ScrollWidth 和 scrollHeight

ScrollWidth 和 scrollHeight:获取元素整个滚动区域的宽、高。包括
width 和 padding,不包括 border和margin。

注意

scrollHeight 的特点是:如果内容超出了盒子,scrollHeight为内容的高(包括超出的内容);如果不超出,scrollHeight为盒子本身的高度。ScrollWidth同理。

静,能寒窗苦守;动,能点石成金。

静,能寒窗苦守;动,能点石成金。

静,能寒窗苦守;动,能点石成金。

静,能寒窗苦守;动,能点石成金。

静,能寒窗苦守;动,能点石成金。

静,能寒窗苦守;动,能点石成金。

打印结果:

2、scrollTop 和 scrollLeft

  • scrollLeft:获取水平滚动条滚动的距离。

  • scrollTop:获取垂直滚动条滚动的距离。

实战经验

当某个元素满足scrollHeight - scrollTop ==
clientHeight时,说明垂直滚动条滚动到底了。

当某个元素满足scrollWidth - scrollLeft ==
clientWidth时,说明水平滚动条滚动到底了。

这个实战经验非常有用,可以用来判断用户是否已经将内容滑动到底了。比如说,有些场景下,希望用户能够看完”长长的活动规则”,才允许触发接下来的表单操作。

scrollTop 的兼容性

如果要获取页面滚动的距离,scrollTop 这个属性的写法要注意兼容性,如下。

(1)如果文档没有 DTD 声明,写法为:

document.body.scrollTop

在没有 DTD 声明的情况下,要求是这种写法,chrome浏览器才能认出来。

(2)如果文档有 DTD 声明,写法为:

document.documentElement.scrollTop

在有 DTD 声明的情况下,要求是这种写法,IE6、7、8才能认出来。

综合上面这两个,就诞生了一种兼容性的写法:

document.body.scrollTop || document.documentElement.scrollTop //方式一

document.body.scrollTop + document.documentElement.scrollTop //方式二

另外还有一种兼容性的写法:window.pageYOffset 和 window.pageXOffset。这种写法无视DTD的声明。这种写法支持的浏览器版本是:火狐/谷歌/ie9+。

综合上面的几种写法,为了兼容,不管有没有DTD,最终版的兼容性写法:

window.pageYOffset || document.body.scrollTop ||
document.documentElement.scrollTop;

判断是否已经 DTD 声明

方法如下:

document.compatMode === “CSS1Compat” // 已声明

document.compatMode === “BackCompat” // 未声明

将 scrollTop 和 scrollLeft 进行封装

这里,我们将 scrollTop 和 scrollLeft
封装为一个方法,名叫scroll(),返回值为
一个对象。以后就直接调用scroll().top 和 scroll().left就好。

代码实现:

上方代码中,函数定义的那部分就是要封装的代码。

另外还有一种比较麻烦的封装方式:(仅供参考)

function scroll() { // 开始封装自己的scrollTop

if(window.pageYOffset !== undefined) { // ie9+ 高版本浏览器

// 因为 window.pageYOffset 默认的是 0 所以这里需要判断

return {

left: window.pageXOffset,

top: window.pageYOffset

}

}

else if(document.compatMode === “CSS1Compat”) { // 标准浏览器
来判断有没有声明DTD

return {

left: document.documentElement.scrollLeft,

top: document.documentElement.scrollTop

}

}

return { // 未声明 DTD

left: document.body.scrollLeft,

top: document.body.scrollTop

}

}

获取 html 文档的方法

获取title、body、head、html标签的方法如下:

  • document.title 文档标题;

  • document.head 文档的头标签

  • document.body 文档的body标签;

  • document.documentElement (这个很重要)。

document.documentElement表示文档的html标签。也就是说,基本结构当中的 html
标签而是通过document.documentElement访问的,并不是通过 document.html
去访问的。

scrollTop 举例:固定导航栏

完整版代码实现:

(1)index.html:

上方代码中,有一个技巧:

main.style.paddingTop = middle.offsetHeight + “px”;

仔细看注释就好。

(2)tools.js:

/**

  • Created by smyhvae on 2018/02/03.

*/

function scroll() { // 开始封装自己的scrollTop

if (window.pageYOffset !== undefined) { // ie9+ 高版本浏览器

// 因为 window.pageYOffset 默认的是 0 所以这里需要判断

return {

left: window.pageXOffset,

top: window.pageYOffset

}

}

else if (document.compatMode === “CSS1Compat”) { // 标准浏览器
来判断有没有声明DTD

return {

left: document.documentElement.scrollLeft,

top: document.documentElement.scrollTop

}

}

return { // 未声明 DTD

left: document.body.scrollLeft,

top: document.body.scrollTop

}

}

实现效果:

工程文件:

  • 2018-02-03-scrollTop固定导航栏.rar

缓动动画

三个函数

缓慢动画里,我们要用到三个函数,这里先列出来:

  • Math.ceil() 向上取整

  • Math.floor() 向下取整

  • Math.round(); 四舍五入

缓动动画的原理

缓动动画的原理就是:在移动的过程中,步长越来越小。

设置步长为:目标位置和盒 子当前位置的十分之一。用公式表达,即:

盒子位置 = 盒子本身位置 + (目标位置 - 盒子本身位置)/ 10;

代码举例:

效果:

缓慢动画的封装(解决四舍五入的问题)

我们发现一个问题,上图中的盒子最终并没有到达400px的位置,而是只到了396.04px就停住了:

原因是:JS在取整的运算时,进行了四舍五入。

我们把打印396.04px这个left值打印出来看看:

我么发现,通过div.style.left获取的值是精确的,通过div.offsetLeft获取的left值会进行四舍五入。

此时,我们就要用到取整的函数了。

通过对缓动动画进行封装,完整版的代码实现如下:

实现效果:

window.scrollTo()方法举例:返回到顶部小火箭

(1)index.html:

我是最顶端…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

生命壹号,永不止步…..

(2)tools.js:

/**

  • Created by smyhvae on 2015/12/8.

*/

//函数:获取scrollTop和scrollLeft的值

function scroll() { // 开始封装自己的scrollTop

if (window.pageYOffset != null) { // ie9+ 高版本浏览器

// 因为 window.pageYOffset 默认的是 0 所以这里需要判断

return {

left: window.pageXOffset,

top: window.pageYOffset

}

}

else if (document.compatMode === “CSS1Compat”) { // 标准浏览器
来判断有没有声明DTD

return {

left: document.documentElement.scrollLeft,

top: document.documentElement.scrollTop

}

}

return { // 未声明 DTD

left: document.body.scrollLeft,

top: document.body.scrollTop

}

}

实现效果:

小火箭的图片资源:


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!