web-dev-qa-db-ja.com

オートコンプリートでは、1.11.0への更新後にiOSで2回クリックする必要があります

JQuery 2.1.0およびjQuery.ui 1.11.0の使用iOS 7でテスト済み。iPhoneおよびiPad Mini。 Androidおよび通常のブラウザで動作します。

問題

最近、jQuery UI 1.10.0から1.11.0にアップグレードしましたが、オートコンプリートの結果リストのアイテムをクリックすると、ホバーが表示されるだけで、同じイベントをもう一度クリックしてクリックイベントを取得する必要があります。これは、バージョン1.10.0では正常に機能していました。

(コメント内のJSFiddleリンク)

動作しないもの

css {cursor: pointer}を使用しても機能しません

onclick=""を使用しても機能しません

(コメント内のJSFiddleリンク)

奇妙な部分

しかし、ここからが面白い部分です。 JSFiddleeditビューでは機能しますが、JSFiddleの「/ show」ページでは機能しません。

JSFiddles:(結果を表示する文字を入力 "s"は良いものです)

私はこれに何日も取り組んできましたが、htmlビューのみをテストする前にJSFiddleで再現することができませんでした。だから今私はあなたに目を向けます。私の人生では、1つのページがクリックイベントをトリガーし、他のページがクリックイベントをトリガーしない理由を理解することはできません。

JQueryオートコンプリートの最も基本的な機能を使用しています。実際、jQuery UIのホームページに表示されているものとまったく同じコードを使用しています。

質問

では、/ showページでiOSのワンクリックでオートコンプリートを機能させるにはどうすればよいですか?

(まだ10人の担当者がいないため、コメントに追加のリンクを投稿します。コメントするのに十分な担当者がいない限り...)

52
Snorre Kim

少し後で

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

何らかの奇妙な理由で@onlydimon's答えは私のために動作しませんでした。イベントmouseenterが必要なようです。次の答えは私のためにうまくいった。

open: function (result) {

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

他のデバイスで壊れないようにするための条件を追加しました。

21

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

イベントのリストをjQueryの「マウス入力」イベントに絞りました。これだけを削除すると、バグが修正されます。また、リストを開くたびに削除する必要はありません。一回だけで十分です。

13
fvsch

私のためにトリックをしているように見える非常に厄介なハックを書きました。これが私がしたことです。

  1. タッチデバイスを使用していることを確認します(私の場合、IAmTouchyと呼ばれる変数)。
  2. オートコンプリート結果のタップ(タッチスタート)を聞きます。
  3. 設定した時間が経過したら、オートコンプリートの結果がまだ表示されているかどうかを確認します。それらがあり、アイテムがフォーカスされている場合、それをクリックします。
  4. (オプション)もう一度試してください...要素が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);
        });
    

うまくいけば誰かがより良い解決策を持っている!

3
Liam Johnston
$.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;
    }
  });
});

これでうまくいきました(drupal 8でも動作します)。iOSデバイスを1回タップすると、検索結果ページにリダイレクトされます。

3
YPatel

オートコンプリートウィジェットには、コードに追加できるイベントが組み込まれています... jqueryui

私は同じ問題を抱えていましたが、最終的にコードをtweekし、1回のクリックでモバイルデバイスに応答させる方法を見つけました。

基本的にモバイルデバイス(iO)の場合、「1回」オートコンプリートリストをタップすると、「フォーカス」イベントがトリガーされます。もう一度クリック(2回目のクリック)すると、イベントが「選択」として読み取られます。そのため、1回のクリックでiOデバイスを強制的に選択するには、最初のクリックで強制的に選択する必要があります。

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

に基づく Liam 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;
    });
1
Raphaël Malié

RaphaëlMaliéのソリューションはほぼ完璧ですが、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;
        });
0
CRK

Fastclick.jsを使用して、この問題を解決します。このjsがタップ遅延300ミリ秒を削除するために使用されることは知っていますが、私にとってもこの問題を解決しました。

  1. FastClick の縮小版をダウンロードします(または、縮小版以外のバージョンをインストールするための指示に従ってください)

  2. ファイルをプロジェクトに含めます。

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

  3. FastClickがロードされた後、FastClickオブジェクトをドキュメントに添付します。

    var attachFastClick = Origami.fastclick;

    attachFastClick(document.body);

注:FastClickを縮小されていない方法で使用しようとすると、つまり:

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

次に使用する

FastClick.attach(document.body);

縮小されたファイルを含めると、エラーが表示されます(FastClickが未定義であることを伝えます)。縮小したファイルを使用している場合は、Origamiからアクセスする必要があります。

0
Swapnil Man

おそらくオートコンプリートの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">
0
Nico

このコードは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);
    }
});
0
cby016

私はjQuery UIとcordovaを使用していますが、アプリにも同じ問題があります。その問題に対する私の解決策は次のとおりです。

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

これにより、選択したアイテムへのフォーカスが停止します。

0
Jorge Mejia