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

标签 javascript jquery ios cordova scroll

我有一个混合移动应用程序,它是针对 phone gap 开发的,仅针对 iOS 设备。我使用 Backbone.js 作为我的 MVC 框架,jQuery、FastClick.js 和 Hammer.js 用于事件。 我有一个可垂直滚动的项目列表。如果我点击一个项目,它应该打开详细信息 View 。如果我在列表未滚动时点击该项目,则效果很好。但是如果我在列表滚动或减速时点击一个项目,它会选择错误的项目并显示其详细信息。 我看着 Tapping on scrolled list generates tap event for wrong element , javascript scroll event for iPhone/iPad?和其他建议我收听滚动列表的 onscroll 事件的网站。每当用户滚动列表时都会触发此事件。我在 onscroll 的回调中禁用了点击事件。我在回调中设置了一个超时为 300 毫秒的计时器,然后在该回调中启用了 tap 事件,该事件在 300 毫秒后执行。如果我在计时器触发之前收到另一个滚动事件,我会取消较早的计时器并再次将其设置为在 300 毫秒后触发。当滚动完全停止时,不会触发其他事件。所以,我只能依赖这个事件。

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

以下是代码片段:

当 View 加载时,绑定(bind)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,请考虑使用“点击”事件来避免大量讨厌的代码来确定滚动是否真的发生。如果您真的需要快速点击,那么这里有一些技巧可以确定滚动是否仍在发生(这是来自内存,所以数字可能会有点偏差)

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

关于javascript - 滚动时点击 Phonegap 移动应用程序会选择不正确的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31010659/

相关文章:

javascript - PouchDB createIndex 抛出 500 错误代码

jquery - 通过箭头键自动建议选择

javascript - 为什么我的汉堡包菜单在两次屏幕大小调整后切换两次而不是只切换一次?

ios - 如何在 flutter 的底部显示切出的字母

ios - UITextView scrollEnabled = YES 在 iOS8 中设置 scrollEnabled = NO 后不工作

ios - iPhone : Using localization change language of an app set it in NSUserDefaults

javascript - 如何在使用 Jquery 时回显 PHP session 变量?

javascript - 单击 RadioButton 时关联的文本框

javascript - Microsoft Doloto(Javascript 缩小器/预取器)的生产就绪替代品?

javascript - 如何显示带标题的 slider ?