【问题标题】:How to Fix JQuery UI Autocomplete in Combination with Touch Punch?如何结合 Touch Punch 修复 JQuery UI 自动完成?
【发布时间】:2017-08-05 02:28:50
【问题描述】:

在将 JQuery UI 与 Touch Punch 结合使用时,自动完成输入字段(在对话框内)中的单词选择无法正常工作。如果自动完成字段直接在 HTML 页面上,而不是在对话框中,它似乎可以工作。 请注意,鼠标选择在所有情况下都可以正常工作,但触摸选择(即在移动设备上)则不行。

我已将整个案例缩减为几行 HTML 和 JavaScript 代码。 一次with JQuery UI Touch Punch,一次without JQuery UI Touch Punch

我能够使用浏览器和操作系统的所有组合重现错误,例如iPhone 上的 Chrome、Android 手机上的 Chrome 以及 iPad 上的 Safari,

如果有人知道解决方法会很好。

【问题讨论】:

  • 也许您可以在您的问题中添加这几行htmljs,以便其他读者可以快速浏览。而且,如果你决定删除你的好例子,这个问题将继续为其他读者提供帮助。

标签: jquery-ui autocomplete mouseevent touch-event touch-punch


【解决方案1】:

我认为这种行为是由于一方面 Touch Punch 开发人员不那么聪明,另一方面 jQuery UI 似乎与 Touch Punch 不太合作。

鼠标事件的触发方式有两种:

  • 浏览器可能会在触摸事件后模拟click 事件
  • 某些库可能会在触摸事件后模拟 click 事件

由于移动浏览器当前模拟点击事件,因此您没有使用 Touch Punch 的示例有效。

那么 Touch Punch 是如何工作的,又是如何搞砸的呢?如果您查看源代码https://github.com/furf/jquery-ui-touch-punch/blob/master/jquery.ui.touch-punch.js,您会发现它用自己的代码包装了$.ui.mouse.prototype._mouseInit,主要目的是为所有继承$.ui.mouse 的小部件附加各种与触摸相关的侦听器。到目前为止,一切都很好。但是那些听众到底在做什么呢? _touchStart 处理程序使用 $.ui.mouse 内部 API 运行检查:

self._mouseCapture(event.originalEvent.changedTouches[0])

检查是否需要模拟鼠标事件。逻辑是:如果小部件中没有点击处理程序,则无需模拟点击。乍一看还不错,但出了什么问题? autocomplete 小部件将其下拉菜单放置在包含对话框的外部上下文中,因此菜单项上的触摸事件实际上会命中由 touch-punch 为对话框注册的侦听器(或者更确切地说是它的 draggableresizable 子-成分)。但是对话框子组件没有点击侦听器,因此库不会模拟事件。此外,您的版本中的draggable(参见https://github.com/jquery/jquery-ui/blob/1-11-stable/ui/draggable.js)调用

this._blurActiveElement( event );

无条件地,这似乎会阻止浏览器生成鼠标事件。所以现在浏览器和库都没有模拟点击事件。

似乎在 jQuery UI 的开发分支中,该错误已修复https://github.com/jquery/jquery-ui/commit/8c66934434214ab92cbcf46240beb739154fdfbf,但原因有点不同。此修复似乎在 jQuery UI 1.12.1 中可用,但在您的 1.12.0

中不可用

所以最简单的解决方案似乎是将jQuery UI升级到1.12.1

https://jsfiddle.net/cjvgv102/1/http://jsfiddle.net/cjvgv102/1/embedded/result/ 上查看使用 jQuery UI 1.12.1 的工作演示

丑陋的黑客攻击(除非你真的不得不这样做,否则就停在这里)

如果由于某些原因您无法升级 jQuery UI,您可以通过在下拉列表中显式创建一个伪造的 mouse 对象并调用其 _mouseInit 来进行破解,这样对话框的子组件将不会处理该事件。

  $( "#demoDlg" ).dialog({
  autoOpen: false,
  modal: true,
  buttons: {
    "Close": function() {
      $( this ).dialog( "close" );
    }
  },
  open: function(event, ui) {
    $( "#words" ).autocomplete({
      source: ["these", "are", "some", "words"]
    });
    // super-hack
    $( "#words" ).autocomplete("instance").menu.element.mouse().mouse("instance")._mouseInit();
  }
});

查看完整演示: https://jsfiddle.net/3ptgks3t/1/

【讨论】:

  • 感谢 SergGr 不幸的是,JQuery UI 1.12.1 版本似乎也不起作用。但是“超级黑客”确实如此。感谢您的分析和帮助!
  • @texasWINthem,看起来我原来的 JSFiddle 链接是错误的,仍然使用 jQuery UI 1.12.0。我更新了链接以实际使用 jQuery UI 1.12.1 (jsfiddle.net/cjvgv102/1/embedded/result),它似乎适用于我的 iPad。如果您仍然需要“破解”,请告诉我,并告诉我您使用什么设备进行测试。
  • 你是对的,使用新链接和 1.12.1 它可以按预期工作。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-20
  • 2014-09-16
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多