Javascript 滚动时点击Phonegap移动应用程序会选择不正确的项目

Javascript 滚动时点击Phonegap移动应用程序会选择不正确的项目,javascript,jquery,ios,cordova,scroll,Javascript,Jquery,Ios,Cordova,Scroll,我用phone gap开发了一款混合移动应用程序,目标是仅针对iOS设备。我使用Backbone.js作为事件的MVC框架,jQuery、FastClick.js和Hammer.js。 我有一个垂直滚动的项目列表。如果我点击一个项目,它会打开详细信息视图。如果我在列表没有滚动的情况下点击该项,则效果良好。但如果在列表滚动或减速时点击某个项目,它会选择错误的项目并显示其详细信息。 我看着 ,以及其他建议我收听滚动列表的onscroll事件的网站。每当用户滚动列表时,就会触发此事件。我在onscro

我用phone gap开发了一款混合移动应用程序,目标是仅针对iOS设备。我使用Backbone.js作为事件的MVC框架,jQuery、FastClick.js和Hammer.js。 我有一个垂直滚动的项目列表。如果我点击一个项目,它会打开详细信息视图。如果我在列表没有滚动的情况下点击该项,则效果良好。但如果在列表滚动或减速时点击某个项目,它会选择错误的项目并显示其详细信息。 我看着 ,以及其他建议我收听滚动列表的
onscroll
事件的网站。每当用户滚动列表时,就会触发此事件。我在onscroll的回调中禁用了tap事件。我在回调中设置了一个超时为300ms的计时器,然后在该回调中启用在300ms后执行的tap事件。如果在计时器触发之前我收到另一个滚动事件,我将取消先前的计时器,并在300ms后再次将其设置为触发。当滚动完全停止时,不会触发其他事件。所以,我只能依靠这个事件

问题是,即使滚动正在减速且未完全停止,也会触发事件。因此,即使列表正在减速且没有停止,计时器也会被触发,我再次遇到错误的详细信息选择问题。当滚动完全停止时,事件再次激发。 如果我将计时器增加到>300ms,则在非动量滚动的情况下,启用轻敲需要更长的时间,用户将持续轻敲多次

以下是代码片段:

加载视图时,绑定
点击
事件和
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,而不是ios 8中引入的WKWebView造成的。如果可以,请切换到使用新的WKWebView。我认为有一些插件可以让你这么做

WKWebView的一个好处是它具有显著更好的滚动事件保真度。事实上,你可能需要去抖动,因为在UIWebView之前,你的应用程序将收到数百个滚动事件,而UIWebView只发送1到3个滚动事件

如果您感兴趣,在滚动期间获得不正确坐标的原因是UIWebView使用GPU滚动可滚动区域的位图,因此它不知道准确的坐标

如果您必须在PuffEGAP中使用UIWebVIEW,请考虑使用“单击”事件来避免大量讨厌的代码来确定滚动是否实际发生。如果您确实需要fastclick,那么这里有几个技巧来确定是否仍在进行滚动(这是从内存中获取的,所以数字可能会有点变小)

  • 根据滚动的速度设置300ms超时变量。您可以通过最后一次
    touchmove
    touchend
    touchcancel
    的x或y差值来确定速度(并使用事件的时间戳)。如果用户轻弹导致高速滚动,则使用2.5秒的超时时间(根据需要调整)。如果是低速滚动,则使用300ms。如果用户只是拖动,因此速度非常低,请使用50毫秒左右的速度
  • 保留一个标记以跟踪代码是否认为它正在滚动。在touchstart上,清除该标志和计时器,因为触摸将停止ui滚动
  • 滚动
    事件处理程序中,如果上一个滚动事件的时间戳超过1.25秒,则这可能是最后一个滚动事件,因此请使用100毫秒的超时。如果这是touchend之后的第一个滚动事件,则使用上面的速度逻辑来确定超时
  • touchend
    /
    touchcancel
    上,检查到可滚动区域边缘的距离。如果接近,则进行补偿,因为滚动将在到达边缘时结束,并产生弹性视觉效果
落选的选民至少可以评论一下为什么落选?谢谢你的详细解释。我已经尝试了一些这样的选择(例如速度计算和相应调整时间),但是我会考虑尝试你提到的其他事情,因为速度单不产生预期的结果。我也在考虑只使用iScroll,以便准确地获取scrollend的事件。