文章目录
  1. 1. 背景
  2. 2. 问题本身
  3. 3. 代码里的滚动条
  4. 4. 其他及扩展出来的点
    1. 4.1. scroll事件
    2. 4.2. scroll
    3. 4.3. jQuery 操作 CSS 的函数
    4. 4.4. 其他容器和位置属性
  5. 5. 教训
  6. 6. 参考

背景

至此,碰到过两次“下拉滚动条去异步加载新数据”的场景,第一次是一个瀑布流,这次是一个列表。
第一次接触瀑布流时,被那高大上的名字唬到了,内心就不知不觉自卑起来,导致思考问题不理智学东西没条理。看似在网搜了不少资料,但都是边边角角,没有一个概况;更不用说先自己想下怎么办,然后再带着问题去搜解决办法。总之,第一次的滚动算是稀里糊涂地做出来了。现在还记得上线后心里的那丝忐忑。
第二次,也就是这次,就想着,再不能糊里糊涂地边编边试了、也不能单纯copy之前做的了。而要把这个“滚动”的小点搞清楚。于是就有了这篇小blog。

问题本身

下拉滚动条动态加载新数据:
1.监听下拉事件:scroll事件 【一滚动就触发,而不等到滚动行为结束,所以-需要合理的加载时机】
2.加载时机:等快滑到底部时,就去请求新数据 【关键点】

而“快达到”其实就是一个临界值的问题。所以,可以把问题进一步简化成“判断滚动条到达底部了”。
对滚动条的感性认识:
1.为什么会出现滚动条? 当要显示的内容的高度 > 父容器的高度时 就会出现纵向滚动条(当然,前提是overflow-y:scroll)
2.滚动条到底部时是个什么状态?滚动条要向下拉的高度 === (内容的高度 - 容器的高度)

脑子里的伪代码是个什么样子呢?
滚动条要向下拉的高度,其实就是: scrollTop() 相对于容器顶部的偏移量
内容的高度以及容器的高度:一般都能直接算出来。所以,问题一下就简单了。

1
2
3
if( 容器.scrollTop() == 内容.height()-容器.height() ){
console.log('滚动条到底部了');
}

如果要加“快到底部”的条件,比如规定个100px的阈值,那代码就是:

1
2
3
if( 100+容器.scrollTop() == 内容.height()-容器.height() ){
console.log('滚动条快要到底部了');
}

考虑到scroll事件是一直触发的,而并不一定恰好刚刚等于,所以就用 <= 代替,如下:

1
2
3
if( 100 >= 内容.height()-容器.height()-容器.scrollTop() ){
console.log('滚动条快要到底部了');
}

代码里的滚动条

jQuery中有三个属性和滚动条的拖动有关,就是: scrollTop、scrollLeft、scrollHeight。
此处,只探讨纵向滚动条,即两个:scrollTop、scrollHeight
把以下代码去浏览器里运行下,然后实时滚动滚动条,去控制台输出 scrollTop 和 scrollHeight 去看看吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div id="container" style="overflow-y:auto; overflow-x:hidden; height:500px; border: 1px solid red;">
<div style="height:750px;"></div>
</div>
<script>
$(document).ready(function (){
var container = $("#container");
var containerHeight = container.height();
container.scroll(function(){
var me = $(this)[0];
var sHeight = me.scrollHeight,
sTop = me.scrollTop;
console.log('\nscrollHeight', sHeight);
console.log('scrollTop', sTop);
if( sTop >= sHeight-containerHeight )
alert("滚动条到底部了");
});
});
</script>

在js代码里,滚动条是被抽象成一个“点”来对待的。
scrollHeight:就是滚动条(一个点)需要滚动的高度,即内部div的高度,750px
scrollTop:表示滚动条(一个点)当前的位置在这750px里占了多少。

说明:
scrollTop() 取值,是返回第一个匹配元素的 scroll top offset
scrollTop() 设置值,是设置所有匹配元素的 scroll top offset

其他及扩展出来的点

scroll事件

scroll事件:在容器的滚动事件里检测和执行if判断,消耗cpu资源。所以,要注意代码(能挪出去的运算就挪出去)
scroll时:效率方面,还有其他注意事项?

scroll

1.scroll事件里,js对象里有滚动
属性4个:scrollTop、scrollLeft、scrollWidth、scrollHeight
方法2个:scrollIntoView() 、scrollViewIfNeeded()
2.jQuery又对scroll做了哪些封装?
因为有 $.scrollTop(),但木有获取高度的。
scrollHeight是否有兼容性问题…

jQuery 操作 CSS 的函数

可以设置|返回css相关属性
1.css()
2.height()、width()
3.scrollTop()、scrollLeft():相对于滚动条顶部|左侧的偏移
4.position():相对于父元素的位置
5.offset():相对于文档的位置
6.offsetParent():最近的定位祖先元素

其他容器和位置属性

$(window).scrollTop() 针对每一个frame //所有浏览器都支持
$(document).scrollTop()

window:
document: 网页可见区域 document.body
注意当浏览器窗口大小改变时(如最大化或拉大窗口后) jQuery(window).height() 随之改变,但是jQuery(document).height()是不变的。

屏幕分辨率的高: window.screen.height;
屏幕分辨率的宽: window.screen.width;
屏幕可用工作区高度: window.screen.availHeight;
屏幕可用工作区宽度:window.screen.availWidth;

教训

碰到问题,不要被华丽的名称吓到。而是先分析这个问题本身。
1.如果要你做,你如何做? 【此时,不要着急问别人也不要着急去网上搜资料,要先自己想,不要怕自己的方法很原始很山寨】
2.里面有几个点?自己准备如何解决?
3.每个点是否有边界条件要考虑 or 还有可改进的空间?
4.再去查别人怎么做。 【此时,和自己的方法做个对比。看哪里想到了、哪里没想到;想到的哪里不一样、没想到的为什么漏掉了。】
5.对比之下,再得结论,即如何解决。

不要怕浪费时间。
准备工作要是不充分,后续不但有坑,而且那种一知半解的状态一点都不可持续。
搞清核心问题,后续干活的时候都会神清气爽,而且以后碰到类似问题都可以轻而易举地解决了。

参考

js判断滚动条是否到底部
jQuery参考手册-CSS操作

文章目录
  1. 1. 背景
  2. 2. 问题本身
  3. 3. 代码里的滚动条
  4. 4. 其他及扩展出来的点
    1. 4.1. scroll事件
    2. 4.2. scroll
    3. 4.3. jQuery 操作 CSS 的函数
    4. 4.4. 其他容器和位置属性
  5. 5. 教训
  6. 6. 参考