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

Het*_*ora 4 javascript jquery scroll ios cordova

我有一个混合移动应用程序开发与手机差距,针对仅iOS设备.我使用Backbone.js作为我的MVC框架,jQuery,FastClick.js和Hammer.js用于事件.我有一个可垂直滚动的项目列表.如果我点击某个项目,它应该打开详细信息视图.如果我在列表不滚动时点击该项目,这可以正常工作.但是如果我在列表滚动或减速时点击某个项目,它会选择错误的项目并显示其详细信息.我看着 攻上滚动列表生成错误的元素敲击事件,iPhone/iPad版的JavaScript滚动事件?和其他建议我收听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));
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

checkScroll功能即使在滚动列表正在减速并且没有完全停止时也会正在触发.如何检测到滚动完全停止且UI不再减速,然后才启用点击事件?有没有其他方法可以解决这个问题?请指教.

Ed *_*lot 6

问题是由PhoneGap默认使用UIWebView而不是WKWebView(ios 8中引入)引起的.如果可以,请切换到使用新的WKWebView.我认为有插件,比如https://github.com/Telerik-Verified-Plugins/WKWebView,可以让你这样做.

WKWebView的一个好处是它具有明显更好的滚动事件保真度.实际上,您可能需要去抖动,因为在UIWebView仅发送1到3个滚动事件之前,您的应用将会收到数百个.

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

如果你必须在PhoneGap中使用UIWebView,请考虑使用"click"事件来避免许多讨厌的代码来确定是否实际发生了滚动.如果你真的需要快速点击,那么这里有几个技巧来确定滚动是否仍在发生(这是来自内存所以数字可能会稍微偏离)

  • 根据滚动的速度使300ms超时变量.您可以根据最后一个touchmovetouchend或的x或y的差异确定速度touchcancel(并使用事件的时间戳真正花哨).如果用户轻弹以产生高速,较长的滚动,则使用2.5秒的超时(根据需要调整).如果是低速滚动,请使用300ms.如果用户只是拖动,那么它的速度确实很低,使用时间约为50ms.
  • 保留一个标记以跟踪您的代码是否认为它正在滚动.在touchstart上,清除该标志和触摸后的计时器将阻止ui滚动
  • scroll事件处理程序中,如果前一个滚动事件的时间戳超过1.25秒,则这可能是最后一个滚动事件,因此使用100ms的超时.如果这是touchend之后的第一个滚动事件,则使用上面的速度逻辑来确定超时.
  • touchend/上touchcancel,检查可滚动区域边缘的距离.如果它接近,则补偿,因为滚动一旦碰到边缘就会结束并产生弹性视觉效果.