起源
想用react做一个无限加载图片的功能,每当页面上滑到一定程度,就继续获取新的图片。具体实现采用了在react根节点添加onScroll属性并编写handleScroll方法。但是编写完成后发现页面滚动并不会触发onScroll事件。
借此,对scroll事件做一些研究,补课……
html和js中的onscroll事件
定义和用法
onscroll 事件在元素滚动条在滚动时触发
//HTML 中:
<element onscroll="myScript">
//JavaScript 中:
object.onscroll=function(){myScript};
//JavaScript 中, 使用 addEventListener() 方法:
object.addEventListener("scroll", myScript);
在定义里,提到了元素滚动条在滚动时,是否意味着这个事件的发生必须满足两个条件
1.元素有滚动条
2.只限于这个元素,也就是所谓的onscroll不冒泡
测试
代码如下,在body和div上都监控scroll事件:
<!DOCTYPE html>
<html>
<head>
<style>
div {
border: 1px solid black;
width: 200px;
height:200px;
text-align:center;
overflow:auto;/*更改此处*/
}
</style>
</head>
<body onscroll="bodyScroll()">
<div>In my younger <br>In my younger <br>In my younger <br>In my younger <br>In my younger <br>In my younger <br>In my younger <br>
</div>
<p>div滚动 <span id="demo">0</span> 次。页面滚动 <span id="demo1">0</span></p>
<div onscroll="divScroll()">In my younger <br>In my younger <br>In my younger <br>In my younger <br>In my younger <br>In my younger <br>In my younger <br>
In my younger <br>In my younger <br>In my younger <br>In my younger <br>In my younger <br>
In my younger <br>In my younger <br>In my younger <br>In my younger <br>In my younger <br>
In my younger <br>In my younger <br>In my younger <br>In my younger <br>In my younger <br>
In my younger <br>In my younger <br>In my younger <br>In my younger <br>In my younger <br></div>
<script>
x = 0;
function divScroll() {
document.getElementById("demo").innerHTML = x += 1;
}
y = 0;
function bodyScroll() {
document.getElementById("demo1").innerHTML = y += 1;
}
</script>
</body>
</html>
当div设置为overflow:scroll/auto时,div具有滚动条,滚动动作必须在div区域内发生div才有反应,而body并没有接收到这个事件;对于div区域外的滚动事件,只有body会对此进行反应
div设置为overflow:visible时,滚动的只是页面,div根本没有滚动条
有以上的结果可知
1.可以接收滚动事件的必须是有滚动条的元素
2.元素过长超出了设定的高度,但是没有设置可出现滚动条时,滚动条逐级上传,一直到有滚动条出现的祖先节点为止
3.滚动事件就像是一对一绑定的一样,仅在符合要求的节点内部发生,且发生的位置没有更内层的节点符合滚动要求,才会触发滚动事件
解决方案
有以上可以,无限加载图片的应用的解决方案有如下几种
1.react根节点定高和overflow:auto,当出现滚动条时就会触发onScroll事件,这时检测react根节点的scrollTop,scrollHeight,clientHeight属性,判断根节点中的图片内容是否下滑至触底
2.react节点自然可被撑开,那么滚动条转移至上层,也就是body节点,这时在body发生的滚动事件是不会被react组件所知的,那么需要让react组件去监控其他的替代事件,比如鼠标事件和触摸事件,并且检测document.body.scrollTop,document.body.scrollHeight,document.documentElement.clientHeight这三个属性来判断下滑是否触底