ios中滚动监听

在部分浏览器(例如:safari)下,手指触发滚动后抬起,此时元素会处于弹性滚动过程,此时这部分浏览器依旧能 实时 监听到滚动事件并做出响应,另外一部分浏览器(例如:UC及微信内嵌浏览器等),当抬手让元素处于弹性滚动过程时,浏览器并不能实时进行事件响应,而是当滚动完全停止后浏览器才会执行事件回调

在ios设备上,为了节约设备事件开销,window.onscroll 触发频率极低,只在停止滚动或页面回到顶部、底部才触发,有时甚至不触发。

后来去google了这方面的文章,几乎都说用 touchmove 代替 scroll,但是这有一个问题,就是 touchmove 的触发频率依旧不如 scroll 的

频率高,当然最重要的问题是,当 touchmove 结束的时候,ios 的页面具有一个类似于惯性的滑动特性,此时发生的滚动,既不能被

window.onscroll 捕获,也不不会执行 touchmove 的代码,甚是蛋疼。

再次,我查到了很多文章说,从 ios8.0 之后苹果放开了 scroll 的触发频率,但是事实摆在眼前,ios8.0后确实会触发大部分事件;但是涉及到fixed定位的元素则不会重新绘制,直到滑动停止才会重新绘制dom(亲测).

1.setInterval

我想到的最简单的办法,就是setInterval, 模拟 scroll 的不间断询问过程。

后来发现,这个方法,行不通。因为 iOS 虽然不会暂停JavaScript执行,但它会暂停绘制。因此,应用程序的JavaScript将继续运行,

但是在滚动操作完成之前,DOM的任何更改都不会被绘制。所以,即使我们监听到了页面发生了滚动,我们也可以进行运算,

但是我们对页面上的元素展现无能为力。无论我们做什么,在滚动停止之前都不会绘制到页面上。

2.使用 touchmove 代替 scroll

touchmove 的触发频率没有 scroll 的频率高,貌似 scroll 每 10px 就会触发一次,但是touchmove 的触发频率似乎与手指移动的距离

有关?但是对于我们监听滑动事件,它的触发频率已经足够高了。

但是 touchmove 事件有一个十分致命的缺点,就是当手指滑动的比较快的时候,手指离开屏幕的时候,滑动并未停止,还是会继续惯性

的滑动一段距离。这个时候,我们是没有办法对这个惯性进行控制的。当然,好消息是,我们可以关闭这个惯性效果:

-webkit-overflow-scrolling 属性控制元素在移动设备上是否使用滚动回弹效果.

auto  :使用普通滚动, 当手指从触摸屏上移开,滚动会立即停止。

touch :使用具有回弹效果的滚动, 当手指从触摸屏上移开,内容会继续保持一段时间的滚动效果。继续滚动的速度和持续的时间和滚动手势的强烈程度成正比。同时也会创建一个新的堆栈上下文。

-webkit-overflow-scrolling: touch; /* 当手指从触摸屏上移开,会保持一段时间的滚动 */
-webkit-overflow-scrolling: auto; /* 当手指从触摸屏上移开,滚动会立即停止 */

但是,上面这么做,虽然可以解决问题,但是会使滑动没有之前的那么灵动。总体来说,可行但是不太完美。

3.touchmove+scroll

$("#page1").on('touchmove', function () {
    // do something
});
//ps:我真的已经尽力了。。但是ios对于scroll的触发频率太低了,只在停止滚动或页面回到顶部、底部才触发
$(window).on("scroll", function (e) {
    // do something   
})

解释一下,通过touchmove,可以精确的控制用户在滑动的时候是会不断的触发滚动事件,并作出响应的。至于滑动后的惯性滑动,

则可以交给 scroll 来处理,应为scroll 正好可以在滚动结束的时候触发一次,这一次触发,刚好可以解决惯性带来的问题。

其实,我们正则匹配 agent 里面的 ios 或者 safari,然后针对这些设备绑定 touchmove 事件,

用于解决安卓 既会触发touch又会触发scroll的尴尬。

至于安卓和chrome,人家很好,不用关心。。。

4.sticky+scroll (吸顶效果可用)

虽然scroll方案行不通,但IOS提供了另一种方式:position: sticky,自IOS 6.1就支持了,最近Chrome56才支持

没有滚过初始位置时,和position: relative表现类似(占据空间,!static能为后代元素提供定位参照),但topleft无效

滚过初始位置时,和position: fixed表现类似,topleft生效,固定在屏幕可见区域,但页面不会抖动

原本占据的空间还在(自带守家占位符的感觉)

但是IOS sticky不由我们控制,且 无法实时获知吸顶状态 ,想要获知吸顶状态的话,又回到了最初的问题,页面滚动过程中,

怎样实时获知滚动条位置?CSS sticky不能解决这个问题

5.模拟滚动

祭出终极解决方案:iscroll!或者完全禁用本机滚动,并使用JavaScript来模仿滚动。

$('window').on('touchmove', function(event) {
    //Prevent the window from being scrolled.
    event.preventDefault();

    //Do something like call window.scrollTo to mimic the scrolling
    //request the user made.
});

iScroll 大体是通过 CSS translation 此类的技术实现的滚动,便于安装和引入,既能够实现平滑的滚动,又可以持续不断的触发滚动事件。


  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS,我们可以使用滚动视图(UIScrollView)来创建一个可以进行滚动的内容视图。在该滚动视图添加按钮,可以通过以下步骤实现: 1. 创建滚动视图对象:使用`UIScrollView`类创建一个滚动视图对象,可以通过代码或者图形化界面编辑器进行创建。 2. 设置滚动范围:通过设置滚动视图的`contentSize`属性,确定滚动内容的大小。内容大小应该大于滚动视图的可见区域,这样才能进行滚动。例如,`scrollView.contentSize = CGSizeMake(320, 600)`。 3. 添加按钮:创建按钮对象,并设置按钮的位置和样式。例如,`UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(50, 50, 100, 50)]`。 4. 将按钮添加到滚动视图:使用`addSubview`方法将按钮对象添加到滚动视图。例如,`[scrollView addSubview:button]`。 5. 设置按钮的位置:通过设置按钮的`frame`属性,确定按钮在滚动视图的位置。需要注意的是,按钮的位置是相对于滚动视图的坐标系的。例如,`button.frame = CGRectMake(50, 50, 100, 50)`。 6. 设置滚动视图的代理:如果需要监听按钮的点击事件,可以将滚动视图的`delegate`属性设置为当前的视图控制器,并实现`UIScrollViewDelegate`协议。例如,`scrollView.delegate = self`。 7. 监听按钮的点击事件:在滚动视图的代理方法,根据需要实现按钮的点击事件处理逻辑。例如,对于点击事件的处理可以通过`UIButton`的`addTarget:action:forControlEvents:`方法或者手势识别器来完成。 以上就是在iOS使用滚动视图添加按钮的基本步骤。根据需要,可以根据具体情况进行定制和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值