我们的移动端项目上一直有一个 BUG:在很多页面里点击某些元素会跳转到另一个页面(如点击列表项进入详情页)。但是如果手机配置较低,有时候如果快速多次点击,可能会重复显示多个目标页面。 即使在微信上也会这种情况,试试快速多次点击“朋友圈”按钮。
解决这个问题需要第一次点击元素总会立即生效,但接下来的一段时间内内如果继续点击这个元素,会直接被忽略掉。
正好一直有在学习 RXJS,它是解决这种事件流的利器。
尝试 debounce
最开始想到的是debounce
操作符,它的“珠宝图”如下:
仔细想想发现不对,它会延迟第一次的点击,第一次点击后的指定时间内没有第二次点击才会生效。
throttleTime
我们需要的是一种和 debounce 正好相反的操作符,也就是我们的throttleTime
。如果指定时间内发射了两个值,debounce
会忽略前一个,throttleTime
会忽略后一个。它的“珠宝图”:
他还有一个相关的操作符throttle
,不是写死的时间间隔,具体参见throttle
封装代码
可以肯定,在整个移动应用间都需要解决上述 BUG,最好的办法是写一个通用的指令,这样大家在用起来时最方便。
1 | import { Directive, EventEmitter, HostListener, Input, OnDestroy, OnInit, Output } from "@angular/core"; |
如何使用
在需要解决上述 BUG 上元素上,将 click 改为 throttleClick 即可,例如
1 | <div tappable (click)="test()">以前大家是这么写的</div> |
改为:
1 | <div tappable (throttleClick)="test()">现在把click改成throttleClick就行啦~~~</div> |
如果觉得 3 秒不合适,也可以改掉
1 | <div tappable (throttleClick)="test()" [throttleTime]="5000">现在时间的阈值改成5秒啦~~~</div> |