如何在移动设备上使Chosen和FastClick正常工作

4
我正在尝试将 FastClick 添加到已经使用 Chosen jQuery 插件的网站上。使用 FastClick 后,移动浏览器上的选择框简单地停止响应轻敲操作。这也可以通过 Chrome 设备仿真进行复制。
您可以在这个简单的 jsFiddle 上自行测试。
<select id="foo">
    <option>Bar</option>
    <option>Asdf</option>
</select>

$("#foo").chosen()

使用Chrome canary复制步骤:

  1. 加载 http://fiddle.jshell.net/7ftdo0j3/3/show/
  2. 打开开发者工具并模拟Google Nexus 7或Apple iPad 1/2(其他设备也可能适用)
  3. 尝试使用选择器。

我尝试按照fastclick文档的说明,将needsclick类添加到所有内容中,但没有成功。 - OlliM
你分享的小提琴无法工作,因为指向 chosen 的外部链接已经失效... 一旦我修复了链接,使用 Chrome 模拟器,它似乎可以正常工作... - T J
有趣的是,在Nexus 10中运行良好,但如果我模拟Nexus 7,则单击选择按钮将打开一个新选项卡,要求推文面板o.0。 - T J
我可以在Chrome上模拟Nexus 10并选择项目,然后获取实际选择的选项。但是,如果我改为模拟7,那么单击选择器会弹出一个新标签页,要求发布到Twitter,而不是打开选择器...很奇怪。 - T J
我更新了jsfiddle链接并添加了复制步骤,我在原始的fiddle中犯了一个愚蠢的错误,FastClick实际上没有加载。 - OlliM
显示剩余4条评论
1个回答

4
你面临的主要问题是尝试同时使用两个库,它们都会奇怪地操作或解释触摸事件。我本想使用短语“它们都在触摸事件中施展黑魔法”,但由于我几乎没有使用这些库的经验,所以感到这可能不合适 ;)
开玩笑的,你的问题的解决方案是向chosen动态创建的所有DOM元素添加FastClick的needsclick类。
$("#test").chosen();
$(".chosen-container *").addClass("needsclick");
FastClick.attach(document.body);

根据我在模拟器上的测试,这似乎可行。我会告诉你为什么我认为它起作用。

我发现当我只将needsclick类添加到div.chosen-container及其直接子元素时,有时触摸会打开下拉菜单,有时不会。当添加到所有子元素时,触摸开始无缺陷地工作。我非常确定这里发生了类似于这样的情况:

  • Chosen动态创建模仿下拉框的div元素。
  • 当用户触摸此类div时,原始的最上层元素被存储在鼠标事件中。
    • 例如:如果用户触摸下拉列表的主要文本(即一个span元素),则该元素被存储在事件中。
  • FastClick仅从此元素检查needsclick
    • 由于没有任何动态创建的元素具有该神奇的类,因此触摸事件被阻止,并且单击事件被发送到该元素。
  • 否则,这会起作用,但是似乎Chosen根本不监听单击事件。您可以通过尝试将单击事件发送到使用jQuery的.chosen-container来测试它:

$(".chosen-container").trigger('click');

它不起作用。但是当您发送一个mousedown事件时,下拉菜单就会打开:

$(".chosen-container").trigger('mousedown');

这可能意味着在触摸设备上,Chosen已经直接侦听touchstarttouchend事件,这意味着您甚至在第一次使用Chosen下拉列表时都不需要FastClick。不幸的是,现在我没有真正的测试设备,所以我不能保证这种愉快的结局:D

我们在一个项目中使用了Chosen,那里也有一些与事件相关的问题。 Chosen源文件中涉及事件绑定的代码相当多,所以我必须说我并不完全确定实际发生了什么。但至少以上的解释在我的奇怪思想中是有意义的。希望能对你有所帮助,并且希望你可以让你的表单再次工作。


感谢您的详细回答。虽然它不是我暗自期望的万能解决方案,但却是迄今为止最好(也是唯一)的答案。关于mousedown的提示非常有用,我将不得不更仔细地查看所选源代码。 - OlliM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接