作者:qixian0392_648 | 来源:互联网 | 2023-08-18 00:59
我有一个混合移动应用程序开发与手机差距,针对仅iOS设备.我使用Backbone.js作为我的MVC框架,jQuery,FastClick.js和Hammer.js用于事件.我有一
我有一个混合移动应用程序开发与手机差距,针对仅iOS设备.我使用Backbone.js作为我的MVC框架,jQuery,FastClick.js和Hammer.js用于事件.
我有一个可垂直滚动的项目列表.如果我点击某个项目,它应该打开详细信息视图.如果我在列表不滚动时点击该项目,这可以正常工作.但是如果我在列表滚动或减速时点击某个项目,它会选择错误的项目并显示其详细信息.
我在看
Tapping on scrolled list generates tap event for wrong element,Javascript scroll event for iPhone/iPad?和其他建议我收听滚动列表的onscroll事件的网站.只要用户滚动列表,就会触发此事件.我在onscroll的回调中禁用了tap事件.我在回调中设置一个定时器,超时为300ms,然后在该回调中启用tap事件,该事件在300 ms后执行.如果在计时器触发之前我得到另一个滚动事件,我取消之前的计时器并再次设置为300ms后触发.当滚动完全停止时,没有其他事件被触发.所以,我只能依靠这个事件.
问题是即使滚动减速并且没有完全停止,事件也会触发.因此,即使列表正在减速并且没有停止,计时器也会被触发,并且我再次遇到错误的详细信息选择问题.当滚动完全停止时,事件再次触发.
如果我将我的计时器增加到> 300毫秒,那么在非动量滚动的情况下,启用点击需要更长的时间并且用户将继续多次点击.
以下是代码段:
加载视图时,绑定tap事件和onscroll事件:
that.$('.scrollListItem').hammer().bind('tap',$.proxy(that.showDetail,that));
this.$('#scrollList').bind('scroll',$.proxy(this.checkscroll,this));
checkscroll功能
checkScroll: function(e){
this.$('.scrollListItem').hammer().unbind('tap');
clearTimeout(myGlobalScrollTimer);
var that = this;
myGlobalScrollTimer = setTimeout(function(){
that.$('.scrollListItem').hammer().bind('tap',$.proxy(that.showDetail,that));
},300);
}
checkScroll功能即使在滚动列表正在减速并且没有完全停止时也会正在触发.
如何检测到滚动完全停止且UI不再减速,然后才启用点击事件?有没有其他方法可以解决这个问题?请指教.
解决方法:
问题是由PhoneGap默认使用UIWebView而不是WKWebView(ios 8中引入)引起的.如果可以,请切换到使用新的WKWebView.我认为有插件,比如https://github.com/Telerik-Verified-Plugins/WKWebView,可以让你这样做.
WKWebView的一个好处是它具有明显更好的滚动事件保真度.实际上,您可能需要去抖动,因为在UIWebView仅发送1到3个滚动事件之前,您的应用将会收到数百个.
如果您感兴趣,滚动期间获得不正确坐标的原因是UIWebView使用GPU滚动可滚动区域的位图,因此它不知道准确的坐标.
如果你必须在PhoneGap中使用UIWebView,请考虑使用“click”事件来避免许多讨厌的代码来确定是否实际发生了滚动.如果你真的需要快速点击,那么这里有几个技巧来确定滚动是否仍在发生(这是来自内存所以数字可能会稍微偏离)
>根据滚动的速度设置300ms超时变量.您可以根据最后一次touchmove和touchend或touchcancel的x或y的diff来确定速度(并使用事件的时间戳真的很花哨).如果用户轻弹以产生高速,较长的滚动,则使用2.5秒的超时(根据需要调整).如果是低速滚动,请使用300ms.如果用户只是拖动,那么它的速度确实很低,使用时间约为50ms.
>保留一个标记以跟踪您的代码是否认为它正在滚动.在touchstart上,清除该标志和触摸后的计时器将阻止ui滚动
>在滚动事件处理程序中,如果前一个滚动事件的时间戳超过1.25秒,则这可能是最后一个滚动事件,因此使用100ms的超时.如果这是touchend之后的第一个滚动事件,则使用上面的速度逻辑来确定超时.
>在touchend / touchcancel上,检查可滚动区域边缘的距离.如果它接近,则补偿,因为滚动一旦碰到边缘就会结束并产生弹性视觉效果.