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

Javascript 自动完成要求您在更新到1.11.0后在iOS中单击两次,javascript,jquery,jquery-ui,ios7,jquery-ui-autocomplete,Javascript,Jquery,Jquery Ui,Ios7,Jquery Ui Autocomplete,使用iOS 7中测试的jQuery 2.1.0和jQuery.ui 1.11.0。iPhone和ipadmini。适用于android和普通浏览器 问题 我们最近从jQueryUI1.10.0升级到1.11.0,现在,当在自动完成结果列表中单击一个项目时,您只会得到一个悬停,您必须再次单击同一个元素才能获得一个单击事件。这在版本1.10.0中可以正常工作 (注释中的JSFIDLE链接) 什么不起作用 使用css{cursor:pointer}不起作用 使用onclick=”“无效 (注释中的JS

使用iOS 7中测试的jQuery 2.1.0和jQuery.ui 1.11.0。iPhone和ipadmini。适用于android和普通浏览器

问题 我们最近从jQueryUI1.10.0升级到1.11.0,现在,当在自动完成结果列表中单击一个项目时,您只会得到一个悬停,您必须再次单击同一个元素才能获得一个单击事件。这在版本1.10.0中可以正常工作

(注释中的JSFIDLE链接)

什么不起作用 使用css
{cursor:pointer}
不起作用

使用
onclick=”“
无效

(注释中的JSFIDLE链接)

奇怪的部分 但有趣/奇怪的部分来了。它可以在JSFIDLE编辑视图中工作,但不能在JSFIDLE“/show”页面上工作

JSFiddles:(键入一个字母以显示结果“s”是一个好的字母)

  • (不起作用)

  • (工程)

我已经为此工作了好几天,但在只测试html视图之前,还不能在JSFIDLE中复制它。现在我来谈谈你。我一辈子都搞不懂为什么一个页面会触发点击事件,而另一个页面不会

我正在使用jQuery最基本的自动完成功能。事实上,使用与jQueryUI主页上显示的代码完全相同的代码

问题 那么,如何让autocomplete在iOS中的/show页面上单击一次就可以工作呢


(我将在评论中发布额外的链接,因为我还没有10个代表。除非我没有足够的代表发表评论…

写了一篇非常讨厌的黑客文章,似乎对我起了作用。这就是我所做的

  • 检查我们使用的是触摸设备(在我的例子中,是一个我称为IAMTOUCH的变量)
  • 聆听自动完成结果上的轻触(touchstart)
  • 在设定的时间后,检查自动完成结果是否仍然可见。如果是,并且某个项目已聚焦,则触发对其的单击
  • (可选)再试一次…以防设置的时间不够长,元素无法获得ui状态焦点类

        $('.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);
        });
    
  • 希望有人能找到更好的解决方案!

    稍晚一点,但是

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

    基于昂立迪蒙的解决方案:

    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')
    

    我将事件列表缩小到只包含jQuery的“mouseenter”事件。仅删除这一个就可以为我修复错误。而且,无需每次打开列表时都删除它;一次就足够了。

    出于某种奇怪的原因,onlydimon的回答对我不起作用。似乎我们确实需要事件
    mouseenter
    。下面的回答是对我来说效果很好

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

    我添加了一个条件,以确保它不会在其他设备中中断。

    使用fastclick.js它将解决此问题。我知道此js用于消除300毫秒的点击延迟,但它也为我解决了此问题

  • 下载的缩小版(或者,您可以按照此处安装非缩小版的说明进行操作)

  • 将文件包括在项目中:

  • 加载FastClick后,将FastClick对象附加到文档:

    var attachFastClick=Origami.fastclick

    attachFastClick(document.body)

  • 注意:如果您尝试使用FAST,请单击非缩小方式,即:

    <script src = "js/fastclick.js"></script>;
    
    然后使用

    FastClick.attach(document.body)


    但是如果包含缩小的文件,您将收到错误(告诉您FastClick未定义)。如果您使用缩小的文件,您必须通过折纸来访问它。

    您可能可以使用autocomplete中的
    focus
    事件

    $(函数(){
    var availableTags=[
    “动作脚本”,
    “AppleScript”,
    “Asp”,
    “基本”,
    “C”,
    “C++”,
    “Clojure”,
    “COBOL”,
    “ColdFusion”,
    “二郎”,
    “Fortran”,
    “好极了”,
    “哈斯克尔”,
    “爪哇”,
    “JavaScript”,
    “口齿不清”,
    “Perl”,
    “PHP”,
    “Python”,
    “红宝石”,
    “斯卡拉”,
    “方案”
    ];
    var selectAction=函数(事件,用户界面){
    //可以对事件和ui对象执行任何操作
    console.log(ui.item)
    }
    $(“#标记”).autocomplete({
    资料来源:availableTags,
    焦点:选择行动,
    选择:选择操作
    });
    });
    
    标签:
    
    基于
    Liam Johnston
    解决方案,我编写了一个在自动对焦设置为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;
        });
    

    Raphaël Malié的解决方案几乎是完美的,但它需要touchend的evt.preventDefault(),否则它将在单击项下的链接/按钮上生成单击

        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;
            });
    

    我正在使用jQuery UI和cordova,我在应用程序中遇到了相同的问题,我的解决方案是:

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

    这将停止对焦所选项目。

    此代码与自动对焦一起工作

    $("#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);
        }
    });
    

    这对我很有效(在drupal 8上也有效)。现在点击iOS设备重定向到搜索结果页面。

    自动完成小部件有一些内置事件,您可以添加到代码中。。。

    我也遇到了同样的问题,最后我想出了如何修改代码并强制移动设备只需点击一下即可做出响应

    基本上,对于移动设备(iOs),当您点击自动完成列表“一次”时,它将触发“焦点”事件,如果您再次点击(第二次点击),它将读取事件为“选择”。因此,为了强制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
      }
    });
    

    其他链接:| |请添加“/显示”当实际测试行为时,将返回到url的末尾。编辑视图会更改行为。此问题的错误报告:这是为我做的。
    menufocus
    是我这边的罪魁祸首。虽然我只需要取消一次,而不是每次打开它。我在react中使用了autocomplete,所以我只将
    if
    语句放在
    componentDidMount
    并使用
    ref
    抓取dom节点。
    $(this.refs.foo.getDOMNode()).autocomplete('widget')。off('menufocus')
    这可以工作,但不会删除键盘
    $("#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
      }
    });