我认为这种行为是由于一方面 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
。到目前为止,一切都很好。但是那些听众到底在做什么呢?处理程序使用内部 API_touchStart
运行检查:$.ui.mouse
self._mouseCapture(event.originalEvent.changedTouches[0])
检查它是否需要模拟鼠标事件。逻辑是:如果小部件中没有点击处理程序,则无需模拟点击。乍一看还不错,但出了什么问题?小autocomplete
部件将其下拉菜单放置在包含对话框的外部上下文中,因此菜单项上的触摸事件实际上会命中通过 touch-punch 为对话框(或者更确切地说是其draggable
和resizable
子组件)注册的侦听器。但是对话框子组件没有点击侦听器,因此库不会模拟事件。此外,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/上的完整演示