html 滚动条停止事件,CSS scroll-snap滚动事件停止及元素位置检测实现
一、Scroll Snap是前端必备技能
CSS Scroll Snap是个非常好用的特性,可以让网页容器滚动停止的时候,无需任何JS代码的参与,浏览器可以自动平滑定位到指定元素的指定位置。类似幻灯片广告效果就可以纯CSS实现。
而且CSS Scroll Snap的兼容性非常好,移动端几乎可以放心使用。
二、源自实际项目的scroll-snap场景
今天下午在实现一个功能需求的时候,正好遇到一个场景非常适合使用Scroll Snap来实现,滑动依次显示人物角色。于是就大胆使用了下,哇,好棒,无需任何js做边界判断,滑动停止自动定位到想要的位置。
关键CSS代码如下:
ul {
width: 375px; height: 667px;
scroll-snap-type: x mandatory;
-webkit-overflow-scrolling: touch;
white-space: nowrap;
overflow-y: hidden;
}
li {
display: inline-block;
width: 100%; height: 100%;
scroll-snap-align: center;
}
滚动父容器元素设置 scroll-snap-type:x mandatory ,水平滚动,强制定位,子列表元素设置 scroll-snap-align:center 让列表在滚动容器的中间显示,于是效果达成。
然而,滚动定位结束后,还需要需要高亮当前定位的人物素材。我发现有些难办了!
以前这种滑动效果用JS实现,无论是JS动画结束,还是CSS动画结束,都是有回调函数可以使用的。但是这里却是滚动,而且滚动后还会自己再定位一会儿,自己定位时间有长有短,谁知道什么时候停止?有时候一口气滑多个元素,也不确定到底停止在哪个元素上。
实际上,标准制定者们和浏览器厂商正在积极推进Scroll Snap相关回调事件的落地,这样可以精确知道滚到什么时候停止以及滚动定位到哪个元素上,但是,标准还在折腾,浏览器还没有支持。项目现在就要用,怎么办呢?
对!肯定要出动JS辅助。
实际上,就算不是Scroll Snap的使用场景,就算是普通的滚动,由于滚动具有惯性,检测滚动是否停止也是一个经常会遇到的需求。因此,有必要捋一个检测滚动什么时候停止的方法。
三、我的滚动中止检测方法
检测元素的滚动是否停止,我的实现思路是这样的,在滚动事件中跑一个定时器,记录当前时间的滚动距离和上一次滚动的距离是否相等,如果相等则认为滚动已经停止,如果不相等,则认为滚动依然在进行。
用JavaScript示意就是( 这个实现已作废 ):
// 定时器,用来检测水平滚动是否结束
var timer = null;
// 上一次滚动的距离
var scrollLeft = 0, scrollTop = 0;
// 滚动事件开始
container.addEventListener('scroll', function () {
clearInterval(timer);
// 重新新的定时器
timer = setInterval(function () {
if (container.scrollLeft == scrollLeft && container.scrollTop == scrollTop) {
// 滚动距离相等,认为停止滚动了
clearInterval(timer);
// ... 做你想做的事情,如回调处理
} else {
// 否则,依然记住上一次滚动位置
scrollLeft = container.scrollLeft;
scrollTop = container.scrollTop;
}
}, 100);
});
如果你有兴趣,可以对上面代码进行进一步封装。
更新于翌日
滚动终止检测可以无需判断前后滚动距离是否相等,因为无论是惯性还是Snap定位scroll事件也是持续触发的。因此,可以直接这样:
// 定时器,用来检测水平滚动是否结束
var timer = null;
// 滚动事件开始
container.addEventListener('scroll', function () {
clearTimeout(timer);
// 重新新的定时器
timer = setTimeout(function () {
// 无滚动事件触发,认为停止滚动了
// ... 做你想做的事情,如回调处理
}, 100);
});
当然,上面提供的方法并不是非常精准的中止检测,因为Scroll Snap最后的重定位浏览器自身有个检测,这个检测事件,根据我的反复研究与测试,应该是 350ms (实际运行可能会略微大几毫秒),远比上面设置的 100ms 要大,因此,会有一次错误的冗余判断,发生在Snap定位开始之前。
我想了想,这个问题无法避免,但也不是什么大问题。总不可能设置 400ms 检测,延迟太高,体验不一定好。
四、当前滚动目标元素检测方法
原理如下,遍历所有的列表元素,检测列表元素的左边缘相对于滚动容器左边缘(如果是左对齐- scroll-snap-align:left )或中心(居中对齐)或右边缘(右对齐)的位置。当然,如果列表元素尺寸和滚动容器尺寸一致,则左中右边缘检测都可以。
JS示意:
[].slice.call(container.children).forEach(function (ele, index) {
if (Math.abs(ele.getBoundingClientRect().left - container.getBoundingClientRect().left) < 10) {
// 此刻的ele元素就是当前定位的元素
// ... 你可以对ele做你想做的事情
} else {
// 此刻的ele元素不是当前定位的元素
}
});
严格来讲,应该计算是否等于 0 ,而不是小于 10 ,这里嘛,加了点容错区间吧。
搞定了上面2个需要JS辅助的需求点,最终的效果就出来了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
html 滚动条停止事件,CSS scroll-snap滚动事件停止及元素位置检测实现相关推荐
- CSS 滚动快照 Scroll Snap
CSS Scroll Snap - CSS(层叠样式表) | MDNCSS 滚动快照是 CSS 的模块,它引入滚动捕捉位置,它强制滚动位置,即 滚动容器的 滚动端口 在滚动操作完成后可能结束的滚动位置 ...
- 译-使用Scroll Snapping实现CSS控制页面滚动
特别声明,本文翻译自@alligatorio的Control Page Scroll in CSS Using Scroll Snapping一文,受限于译者能力,译文或存在不足,欢迎大家指出.如需转 ...
- html屏幕滚动事件监听,JQuery监听页面滚动事件
1.当前滚动的地方的窗口顶端到整个页面顶端的距离: var scrollTop = $(window).scrollTop(); 2.获取指定元素的页面位置: $(obj).offset().top; ...
- 学习CSS Scroll Snapping与scroll-snap-align
假如有个Web页面是一块一块的,如下图所示: 我们希望可以一块一块的滚动,比如当前一个块滚出去了一部分并且后一个块滚进来一部分的时候,实现后一个块自动滚入或者前一个块回弹到初始位置这种效果,以前的时候 ...
- vue 监听页面滚动事件:触发animate.min.css动画特效
一.问题答疑: 1. animate.css 如何在vue项目中引入?或引用? 2. 如何监听滚动事件,触发animate.class动画播放? vue 监听滚轮滚动事件,for循环 ,动态id,代码 ...
- jquery滚动条滚动事件_滚动条和jQuery –使用航点的事件处理
jquery滚动条滚动事件 How to handle scrolling with jQuery. Today we continue jQuery reviews, and our article ...
- 关于IOS设备window onscroll滚动条滚动事件不触发的问题
http://blog.hooperui.com/%E5%85%B3%E4%BA%8Eios%E8%AE%BE%E5%A4%87window-onscroll%E6%BB%9A%E5%8A%A8%E6 ...
- 综合设计一个OPPE主页--页面的插件引用(animate.css)--d动画的使用--滚轮或鼠标到该位置时,才有动画的切换---所以我们需要用jquery监听鼠标滚轮的滚动事件
Animate.css | A cross-browser library of CSS animations. 里面有许多css的效果 首先使用 animate.css文件 link rel=&qu ...
- JS网页滚动条滚动事件实例分析
js网页滚动条滚动事件的用法,在javascript中window.onscroll监控滚动条滚动事件的相关技巧 本文实例讲述了js网页滚动条滚动事件用法,具体分析如下: 在做js返回顶部的效果时,要 ...
最新文章
- python3 获取异常类型
- 进程间的通信方式(二):管道Pipe和命令管道FIFO
- c语言拟合线性直线误差最小,急~~~~~~!!!求解!用C语言编写最小二乘法求数据的拟合曲线~并做出图显示拟合效果!高分悬赏!...
- pyinstaller打包pyqt文件(转)
- 12 | 套路篇:CPU 性能优化的几个思路
- 全国计算机一级知识题及答案解析,全国计算机等级考试一级试题库大全完整版附参考答案...
- Linux 命令(81)—— chmod 命令
- oracle更改字段大小语句,sql语句修改字段长度(实例)
- dmg2iso使用及转换DMG文件遇到的问题
- 卡顿、画面撕裂、延迟、晕眩为什么与帧率、刷新率有关
- 【IoT】STM32 启动代码汇编指令详解
- 必看!!作为电工,你为什么要学PLC?
- Gson 测试环境 date转换抛异常
- 作为程序员如何赚到第一桶金?
- 5G到底什么时候来,以及,它究竟能给我们带来什么?
- canvas小虫子(利用canvas形成多个形状类似虫子的线条)
- 4501. 收集卡牌
- 如何进入docker系统
- 自然语言处理学习笔记-lecture08-语义分析
- 教您在CorelDRAW中安装字体
热门文章
- 一个简单的小技巧,监控网页所有动态标签创建的调用处
- tomcat使用manager GUI应用和script分别reload应用的注意事项
- SAP Cloud Platform Neo环境的权限管理
- SAP Analytics Cloud导入数据的规模限制
- CRM Fiori Application top N Opportunity
- One order event display tool
- 解析word template返回使用的webservice WSDL和Operation
- 列出系统所有未被Business transaction 引用的Products集合
- How CRM_JEST is influenced by status change in WebUI
- HelloWorldProxy is a factory bean