简体   繁体   English

自动完成功能要求您在更新到1.11.0后在iOS中单击两次

[英]Autocomplete requires you to click twice in iOS after update to 1.11.0

Using jQuery 2.1.0 and jQuery.ui 1.11.0 Tested in iOS 7. iPhone and iPad Mini. 使用jQuery 2.1.0和jQuery.ui 1.11.0在iOS 7中进行了测试。iPhone和iPad Mini。 Works on android and regular browsers. 适用于android和常规浏览器。

The problem 问题

We recently upgraded from jQuery UI 1.10.0 to 1.11.0 and now, when clicking an item in an autocomplete results list, you only get a hover, you have to click the same element again to get a click event. 我们最近从jQuery UI 1.10.0升级到1.11.0,现在,当单击自动完成结果列表中的项目时,您只会悬停鼠标,必须再次单击相同的元素才能获得click事件。 This used to work fine with version 1.10.0. 以前在1.10.0版中可以正常工作。

(JSFiddle link in comments) (注释中的JSFiddle链接)

What does not work 什么不起作用

using css {cursor: pointer} does not work 使用CSS {cursor: pointer}不起作用

using onclick="" does not work 使用onclick=""不起作用

(JSFiddle link in comments) (注释中的JSFiddle链接)

The weird part 怪异的部分

But here comes the fun/weird part. 但是有趣/奇怪的部分到了。 It works in JSFiddle edit view, but not on the JSFiddle "/show" page. 它可以在JSFiddle 编辑视图中使用,但不能在JSFiddle“ / show”页面上使用。

JSFiddles: (type a letter to show results "s" is a good one) JSFiddles :( 键入字母以显示结果“ s”是一个很好的结果)

I've been working on this for days, but hadn't been able to reproduce it in JSFiddle before testing only the html view. 我已经为此工作了好几天,但是在仅测试html视图之前无法在JSFiddle中重现它。 So now I turn to you. 所以现在我转向你。 I can't for the life of me figure out why the one page triggers a click event, and the other does not. 我一辈子都无法弄清楚为什么一页触发一次点击事件,而另一页却不触发点击事件。

I am using the most basic function of jQuery autocomplete. 我正在使用jQuery自动完成功能的最基本功能。 In fact, using the exact same code that is presented on jQuery UI's home page. 实际上,使用与jQuery UI主页上显示的代码完全相同的代码。

The question 问题

So, how do I get autocomplete to work with one click in iOS on the /show page? 那么,如何在/ show页面上的iOS中单击一次即可获得自动完成功能?

(I will post additional links in comments because I don't have 10 rep yet. Unless I don't have enough rep to comment...) (我将在评论中发布其他链接,因为我还没有10位代表。除非我没有足够的代表来评论...)

Just a bit later, but 稍后,但是

$("#input").autocomplete({
    open: function(event, ui) {
        $('.ui-autocomplete').off('menufocus hover mouseover mouseenter');
    }
});

For some strange reason @onlydimon's answer didn't work for me. 由于某些奇怪的原因, @onlydimon's答案对我不起作用。 It seems like we do need event mouseenter . 看来我们确实需要事件mouseenter Following answer worked well for me. 以下答案对我来说效果很好。

open: function (result) {

            if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
                $('.ui-autocomplete').off('menufocus hover mouseover');
            }
        },

I have added a condition to make sure that it doesn't break in other devices. 我添加了一个条件,以确保它不会在其他设备中损坏。

Building on onlydimon's solution: 基于onlydimon的解决方案:

var input = $("#input")
// Initialize autocomplete
input.autocomplete()
// Retrieve the autocomplete list and remove the mouseenter event
// which seems to trip up iOS Safari
input.autocomplete('widget').off('mouseenter')

I narrowed down the list of events to just jQuery's 'mouseenter' event. 我将事件列表缩小为仅jQuery的“ mouseenter”事件。 Removing just this one fixes the bug for me. 删除仅此一个修复了我的错误。 Also, no need to remove it every time the list is opened; 另外,每次打开列表时都无需将其删除; once is enough. 一次就够了。

Wrote a super nasty hack which seems to do the trick for me. 写了一个超级讨厌的hack,这似乎对我有用。 Here's what I did. 这就是我所做的。

  1. Check that we're using a touch device (in my case, a variable I have called IAmTouchy. 检查我们是否正在使用触摸设备(在我的情况下,我称为IAmTouchy的变量。
  2. Listen for a tap (touchstart) on an autocomplete result. 聆听自动完成结果上的点击(触摸开始)。
  3. After a set time, check to see if the autocomplete results are still visible. 在设定的时间后,检查自动完成结果是否仍然可见。 If they are, and an item is focussed, trigger a click on it. 如果它们对齐并且某个项目已聚焦,则触发对其的单击。
  4. (optional) Try once more... in case the set time wasn't long enough for the element to gain the ui-state-focus class. (可选)再试一次...以防设置时间不够长,以至于该元素无法获得ui-state-focus类。

      $('.autocompleteContainer').on('touchstart', 'li.ui-menu-item', function(){ var $container = $(this).closest('.autocompleteContainer'), $item = $(this); //if we haven't closed the result box like we should have, simulate a click on the element they tapped on. function fixitifitneedsit() { if ($container.is(':visible') && $item.hasClass('ui-state-focus')) { $item.trigger('click'); return true; // it needed it } return false; // it didn't } setTimeout(function () { if (!fixitifitneedsit()) { setTimeout(fixitifitneedsit, 600); } }, 600); }); 

Hopefully someone has a nicer solution though! 希望有人能提供更好的解决方案!

$.ajax({
 url: '/ajax/xyz.json'
})
.done(function( data ) {
  $('#id').autocomplete({
    source: data,
    open: function( event, ui ) {
        if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
          $('.ui-autocomplete').off('menufocus hover mouseover mouseenter');
        }
    },
    select: function( event, ui ) {
      window.location.href = ui.item.value;
      return false;
    }
  });
});

This worked for me (works on drupal 8 as well). 这对我有用(也适用于drupal 8)。 Now one tap on iOS devices redirect to search result page. 现在,在iOS设备上一按即可重定向到搜索结果页面。

Based on Liam Johnston solution, I wrote this one which work for me with autoFocus set to true: 基于Liam JohnstonLiam Johnston解决方案,我编写了一个适用于我的方法,将autoFocus设置为true:

var movedWhildAutocomplete = false;
$(document)
    .on('touchstart', '.ui-autocomplete li.ui-menu-item', function(){
        $(this).trigger('mouseenter');
        movedWhildAutocomplete = false;
    })
    .on('touchmove', '.ui-autocomplete li.ui-menu-item', function(){
        movedWhildAutocomplete = true;
    })
    .on('touchend', '.ui-autocomplete li.ui-menu-item', function(){
        if (!movedWhildAutocomplete) {
            var $el = $(this);
            if ($el.is(':visible') && $el.hasClass('ui-state-focus')) {
                $el.trigger('click');
            }
        }
        movedWhildAutocomplete = false;
    });

Autocomplete widget has some built in events that you can add on to your code... jqueryui 自动完成构件有内建的事件,你可以添加到您的代码... jQueryUI的

I was having the same problem and finally figured out how to tweek the code and force mobile devices to respond with one click. 我遇到了同样的问题,最后想出了如何对代码进行修改并强制移动设备一键响应。

Basically for mobile devices (iOs) when you tap on the autocomplete list 'once', it will trigger the "focus" event, if you click once more (2nd click) it will read the event as "select". 基本上对于移动设备(iO),当您点击自动完成列表“一次”时,它将触发“焦点”事件,如果再次单击(第2次单击),它将读取该事件为“选择”。 So in order to force iOs devices to select on one click you have to force it to select on the first click. 因此,为了强制iOs设备单击一次,您必须强制其选择第一次单击。

$("#input").autocomplete({
  source: yourSourceList,
  focus: function(event, ui) {
    $(this).val(ui.item.value);
    $(".ui-menu").hide(); //you can also console.log(ui.item.value); for the selected widget object
  }
});

Use fastclick.js it will solve this problem. 使用fastclick.js它将解决此问题。 I know this js is used for removing 300ms tap delay but it solved this problem also for me. 我知道这个js用于消除300ms的抽头延迟,但它也为我解决了这个问题。

  1. Download the minified version of FastClick (alternatively, you can follow the instructions for installing the non-minified version here) 下载FastClick的精简版(或者,您可以按照此处的说明安装非精简版)

  2. Include the file in your project: 将文件包括在您的项目中:

    <script src = "js/fastclick.min.js"></script> <script src =“ js / fastclick.min.js”> </ script>

  3. Attach the FastClick object to the document after FastClick has been loaded: 加载FastClick之后,将FastClick对象附加到文档:

    var attachFastClick = Origami.fastclick; var attachFastClick = Origami.fastclick;

    attachFastClick(document.body); attachFastClick(document.body的);

NOTE: If you try using FastClick the non-minified way, ie: 注意:如果您尝试以非最小化方式使用FastClick,即:

<script src = "js/fastclick.js"></script>;

Then use 然后使用

FastClick.attach(document.body); FastClick.attach(document.body的);

but are including the minified file you will receive errors (telling you that FastClick is undefined). 但如果包含缩小的文件,则会收到错误消息(告诉您FastClick未定义)。 If you are using the minified file you must access it through Origami. 如果使用缩小文件,则必须通过折纸进行访问。

you can probably can use the focus event from autocomplete! 您可能可以使用自动完成功能中的focus事件!

focus( event, ui ) 焦点(事件,用户界面)

 $(function() { var availableTags = [ "ActionScript", "AppleScript", "Asp", "BASIC", "C", "C++", "Clojure", "COBOL", "ColdFusion", "Erlang", "Fortran", "Groovy", "Haskell", "Java", "JavaScript", "Lisp", "Perl", "PHP", "Python", "Ruby", "Scala", "Scheme" ]; var selectAction = function(event, ui) { //do whatever you want with event and ui objects console.log(ui.item) } $("#tags").autocomplete({ source: availableTags, focus: selectAction, select: selectAction }); }); 
 <script src="//code.jquery.com/jquery-1.10.2.js"></script> <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script> <label for="tags">Tags:</label> <input id="tags"> 

Solution from Raphaël Malié is almost perfect, but it needs evt.preventDefault() for touchend, otherwise it will generate a click on a link/button that is under clicked item. 来自RaphaëlMalié的解决方案几乎是完美的,但它需要evt.preventDefault()作为touchend,否则它将在被单击项下方的链接/按钮上产生单击。

    var movedWhildAutocomplete = false;
    $(document)
        .on('touchstart', '.ui-autocomplete li.ui-menu-item', function(){
            $(this).trigger('mouseenter');
            movedWhildAutocomplete = false;
        })
        .on('touchmove', '.ui-autocomplete li.ui-menu-item', function(){
            movedWhildAutocomplete = true;
        })
        .on('touchend', '.ui-autocomplete li.ui-menu-item', function(evt){
            if (!movedWhildAutocomplete) {
                var $el = $(this);
                if ($el.is(':visible') && $el.hasClass('ui-state-focus')) {
                    evt.preventDefault();
                    $el.trigger('click');
                }
            }
            movedWhildAutocomplete = false;
        });

I´m working with jQuery UI with and cordova, and I have the same problem in the app, my solution for that problem is this: 我正在使用带有和cordova的jQuery UI,并且在应用程序中存在相同的问题,针对该问题的解决方案是:

$('.ui-autocomplete').mouseenter( function( e ){
    e.preventDefault();
    e.stopPropagation();
});

This stop the focus on the selected item. 这将停止将焦点放在所选项目上。

This code works with autoFocus 此代码与autoFocus一起使用

$("#input").autocomplete({
    source: ["Test 1", "Test 2", "Test 3", "Test 4", "Test 5"],
    autoFocus: true,
    focus: function(event, ui) {
        if (navigator.userAgent.match(/(iPod|iPhone|iPad)/) && event.bubbles) {
            $(this).data("ui-autocomplete")._trigger("select", "autocompleteselect", {item: ui.item} );
            $(this).autocomplete("close");
        }
        return false;
    },
    select: function(event, ui) {
        $(this).val(ui.item.label);
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM