Phonegap移动应用程序点击时滚动选择不正确的项目 [英] Phonegap mobile app tapping while scrolling selects incorrect item

查看:116
本文介绍了Phonegap移动应用程序点击时滚动选择不正确的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用手机差距开发的混合移动应用,仅针对iOS设备。我使用Backbone.js作为我的MVC框架,jQuery,FastClick.js和Hammer.js的事件。
我有一个可以垂直滚动的项目列表。如果我点击一个项目,它应该打开详细信息视图。这工作正常,如果我点击项目时,列表不滚动。但是如果我在列表滚动或减速时点击一个项目,它会选择错误的项目并显示其详细信息。
我查看了
敲击在滚动列表中生成错误元素的点击事件 JavaScript滚动事件的iPhone / iPad?和其他网站建议我收听我的滚动列表的 onscroll 事件。只要用户滚动列表,就会触发此事件。我禁用tap事件在onscroll的回调。我在回调中设置一个定时器,超时为300ms,然后在该回调中启用tap事件,在300ms之后执行。如果我在定时器触发之前得到另一个滚动事件,我取消较早的定时器,并将其重新设置为在300ms后触发。当滚动完全停止时,没有其他事件被触发。所以,我只能依靠这个事件。

I have a hybrid mobile app developed with phone gap and targeted for iOS only devices. I use Backbone.js as my MVC framework, jQuery, FastClick.js and Hammer.js for events. I have a list of items which is vertically scrollable. If I tap on an item, it should open the details view. This works fine if I tap on the item when the list is not scrolling. But if I tap on an item while the list is scrolling or decelerating, it selects the wrong item and shows its details. I looked at Tapping on scrolled list generates tap event for wrong element, javascript scroll event for iPhone/iPad? and other sites which suggest that I listen to the onscroll event of my scrolling list. This event is fired whenever the user scrolls the list. I disable the tap event in the callback for onscroll. I set a timer in the callback with timeout of 300ms and then enable the tap event in that callback which executes after 300 ms. If I get another scroll event before the timer fires, I cancel the earlier timer and set it again to fire after 300ms. There is no other event that gets fired when the scrolling stops completely. So, I have to rely on this event only.

问题是事件触发,即使当滚动正在减速而不是完全停止。由于这个原因,即使列表减速并且未停止,我也会触发计时器,并且我再次遇到错误的细节选择问题。当滚动完全停止时,事件再次触发。
如果我将我的计时器增加到> 300ms,那么在非动量滚动的情况下,点击被启用需要更长的时间,并且用户将继续多次点击。

The issue is the event fires even when the scrolling is decelerating and not completely stopped. Due to this, the timer gets fired even while the list is decelerating and not stopped and I run into the wrong details selection issue again. The event fires again when the scroll stops completely as well. If I increase my timer to be >300ms, then in case of non-momentum scroll, it takes longer for the tap to be enabled and the user will keep tapping multiple times.

下面是代码片段:

当视图加载时,绑定点击 onscroll 事件:

When view loads, bind the tap event and the onscroll event:

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不再减速,然后只启用轻击事件?有没有其他方法来解决这个问题?请求建议。

The checkScroll function is firing currently even while the scroll list is decelerating and it hasn't stopped completely. How do I detect that the scrolling is completely stopped and the UI is no longer decelerating and only then enable the tap event? Is there any other way to solution this? Please advice.

推荐答案

问题是PhoneGap默认使用UIWebView,而不是WKWebView )。如果可以,切换到使用新的WKWebView。我认为有插件,如 https://github.com/Telerik-Verified-Plugins/WKWebView ,让你这样做。

The problem is caused by PhoneGap still using UIWebView by default, instead of WKWebView (that was introduced in ios 8). If you can, switch to using the new WKWebView. I think there's plugins, like https://github.com/Telerik-Verified-Plugins/WKWebView, that let you do this.

WKWebView的一个好处是它有更好的滚动事件保真度。事实上,你可能需要去反弹,因为你的应用程序将收到数百个UIWebView之前只发送1和3滚动事件之间的地方。

One of the benefits of WKWebView is that it has significantly better scroll event fidelity. In fact, you'll probably need to debounce since your app will receive hundreds where before UIWebView only sends somewhere between 1 and 3 scroll events.

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

In case you are interested, the reason you get the incorrect coordinate during scrolling is that UIWebView uses the GPU to scroll a bitmap of your scrollable area so it doesn't know the accurate coordinates.

如果您必须使用UIWebView在PhoneGap,考虑使用点击事件,以避免大量讨厌的代码,以确定滚动是否实际发生。如果你真的需要fastclick,那么这里有几个技巧来确定滚动是否仍然发生(这是从内存,因此数字可能会有点)

If you have to use UIWebView in PhoneGap, consider using the "click" event to avoid lots of nasty code to determine if whether scrolling is actually happening. If you really need fastclick, then here's a couple of tricks to determine if scrolling is still happening (this is from memory so numbers might be off a bit)


  • 根据滚动速度设置300ms超时变量。您可以根据最后一个 touchmove touchend 或<$ c的x或y的diff来确定速度$ c> touchcancel (并使用事件的时间戳真的很奇怪)。如果用户轻弹导致高速度,长时间滚动使用2.5秒的超时(调整为适合)。如果是低速滚动,请使用300ms。如果用户只是拖动,所以它是真正的低速使用大约50ms。

  • 保留一个标志来跟踪你的代码是否认为它是滚动。在触摸启动时,清除该标志和自触摸起的计时器将停止ui滚动

  • 滚动事件处理程序中,如果上一个滚动事件的时间戳大于1.25秒,这可能是最后一个滚动事件,因此使用100ms的超时。如果这是touchend之后的第一个滚动事件,那么使用上面的速度逻辑来确定超时。

  • touchend c $ c> touchcancel ,检查到可滚动区域边缘的距离。如果它接近,补偿,因为滚动将结束一旦它撞到边缘,并产生弹性视觉效果。

  • Make your 300ms timeout variable based on the velocity of the scroll. You can determine the velocity from the diff of the x or y of the last touchmove and the touchend or touchcancel (and use the events' timestamps to be really fancy). If the user flicked to cause a high-velocity, longer scroll use a timeout of 2.5 seconds (tweak as you see fit). If it was a low-velocity scroll, use 300ms. If the user was just dragging so it was really low velocity use around 50ms.
  • Keep a flag to track whether your code thinks it is scrolling. On a touchstart, clear that flag and the timer since touch will stop the ui from scrolling
  • In a scroll event handler, if the previous scroll event's timestamp was more than 1.25 second this is probably the last scroll event so use a timeout of 100ms. If this is the first scroll event after touchend, then use the velocity logic above to determine timeout.
  • On the touchend/touchcancel, check the distance to the edge of the scrollable area. If it is close, compensate since scrolling will end once it hits the edge and does the elastic visual effect.

这篇关于Phonegap移动应用程序点击时滚动选择不正确的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆