一、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滚动事件停止及元素位置检测实现相关推荐

  1. CSS 滚动快照 Scroll Snap

    CSS Scroll Snap - CSS(层叠样式表) | MDNCSS 滚动快照是 CSS 的模块,它引入滚动捕捉位置,它强制滚动位置,即 滚动容器的 滚动端口 在滚动操作完成后可能结束的滚动位置 ...

  2. 译-使用Scroll Snapping实现CSS控制页面滚动

    特别声明,本文翻译自@alligatorio的Control Page Scroll in CSS Using Scroll Snapping一文,受限于译者能力,译文或存在不足,欢迎大家指出.如需转 ...

  3. html屏幕滚动事件监听,JQuery监听页面滚动事件

    1.当前滚动的地方的窗口顶端到整个页面顶端的距离: var scrollTop = $(window).scrollTop(); 2.获取指定元素的页面位置: $(obj).offset().top; ...

  4. 学习CSS Scroll Snapping与scroll-snap-align

    假如有个Web页面是一块一块的,如下图所示: 我们希望可以一块一块的滚动,比如当前一个块滚出去了一部分并且后一个块滚进来一部分的时候,实现后一个块自动滚入或者前一个块回弹到初始位置这种效果,以前的时候 ...

  5. vue 监听页面滚动事件:触发animate.min.css动画特效

    一.问题答疑: 1. animate.css 如何在vue项目中引入?或引用? 2. 如何监听滚动事件,触发animate.class动画播放? vue 监听滚轮滚动事件,for循环 ,动态id,代码 ...

  6. jquery滚动条滚动事件_滚动条和jQuery –使用航点的事件处理

    jquery滚动条滚动事件 How to handle scrolling with jQuery. Today we continue jQuery reviews, and our article ...

  7. 关于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 ...

  8. 综合设计一个OPPE主页--页面的插件引用(animate.css)--d动画的使用--滚轮或鼠标到该位置时,才有动画的切换---所以我们需要用jquery监听鼠标滚轮的滚动事件

    Animate.css | A cross-browser library of CSS animations. 里面有许多css的效果 首先使用 animate.css文件 link rel=&qu ...

  9. JS网页滚动条滚动事件实例分析

    js网页滚动条滚动事件的用法,在javascript中window.onscroll监控滚动条滚动事件的相关技巧 本文实例讲述了js网页滚动条滚动事件用法,具体分析如下: 在做js返回顶部的效果时,要 ...

最新文章

  1. python3 获取异常类型
  2. 进程间的通信方式(二):管道Pipe和命令管道FIFO
  3. c语言拟合线性直线误差最小,急~~~~~~!!!求解!用C语言编写最小二乘法求数据的拟合曲线~并做出图显示拟合效果!高分悬赏!...
  4. pyinstaller打包pyqt文件(转)
  5. 12 | 套路篇:CPU 性能优化的几个思路
  6. 全国计算机一级知识题及答案解析,全国计算机等级考试一级试题库大全完整版附参考答案...
  7. Linux 命令(81)—— chmod 命令
  8. oracle更改字段大小语句,sql语句修改字段长度(实例)
  9. dmg2iso使用及转换DMG文件遇到的问题
  10. 卡顿、画面撕裂、延迟、晕眩为什么与帧率、刷新率有关
  11. 【IoT】STM32 启动代码汇编指令详解
  12. 必看!!作为电工,你为什么要学PLC?
  13. Gson 测试环境 date转换抛异常
  14. 作为程序员如何赚到第一桶金?
  15. 5G到底什么时候来,以及,它究竟能给我们带来什么?
  16. canvas小虫子(利用canvas形成多个形状类似虫子的线条)
  17. 4501. 收集卡牌
  18. 如何进入docker系统
  19. 自然语言处理学习笔记-lecture08-语义分析
  20. 教您在CorelDRAW中安装字体

热门文章

  1. 一个简单的小技巧,监控网页所有动态标签创建的调用处
  2. tomcat使用manager GUI应用和script分别reload应用的注意事项
  3. SAP Cloud Platform Neo环境的权限管理
  4. SAP Analytics Cloud导入数据的规模限制
  5. CRM Fiori Application top N Opportunity
  6. One order event display tool
  7. 解析word template返回使用的webservice WSDL和Operation
  8. 列出系统所有未被Business transaction 引用的Products集合
  9. How CRM_JEST is influenced by status change in WebUI
  10. HelloWorldProxy is a factory bean