web-dev-qa-db-ja.com

タッチスクリーンでのホバーイベントの処理

私が設計したWebサイトは、:hoverにサブメニューを表示するナビゲーションメニューを使用しています。最初のサイトはレスポンシブデザインを使用していませんでした。デスクトップサイトのみをターゲットにしています。現在、レスポンシブデザイン手法を使用して、モバイルデバイスやタブレットをターゲットにしています。その多くは、マウスベースではなくタッチベースです。

私が直面していた大きな問題(そして他の多くの人々も直面しているようです)は、ホバーベースのナビゲーションメニューでした:マウス環境ではうまく機能しますが、タッチデバイスでは、ホバーをトリガーする確実な方法がなく、使いにくいページ。

目標はこれです:

  1. メニューをマウスでホバーすると、サブメニューが表示されます。
  2. マウスでメニューをクリックするとアンカータグのリンクが開きます。
  3. 初めてメニューをタッチしたときは、サブメニューを表示します。
  4. メニューを2回目にタッチしたときに、アンカータグのリンクを開きます。
  5. マウスデバイスも接続されているタブレットの機能をシームレスに切り替えます。

私のチームは、マウスベースのマシンでのホバー効果を犠牲にするつもりはありません。彼らはそれを好み、すべてのデバイスに基づいてメニューをクリックさせたくありません。これに同意する。

ネットを見回した後、自分の問題に対する単一の解決策を見つけることができませんでした。それらのいくつかを組み合わせて、Androidで十分にテストされたものを開発し、望みどおりの機能を実現しました。改善できることはありますか、このアプローチに問題がありますか?

jQuery(document).ready(function() {
    var touched=false;
    jQuery(".nav").on('touchstart', 'li .has_children', function (e) {  touched=true; });
    jQuery("html").on('mousemove', function (e) { touched=false; });

    jQuery("html").on('click', updatePreviousTouched );

    jQuery(".nav").on('click', 'li .has_children', function (e) {
        updatePreviousTouched(e);
        if( touched ) { 
            if (jQuery(this).data('clicked_once')) {
                jQuery(this).data('clicked_once', false);
                return true;
            } else {
                e.preventDefault();
                jQuery(this).trigger("mouseenter"); 
                jQuery(this).data('clicked_once', true);

            }
        }
        touched=false;
    }); 

    var previous_touched;
    function updatePreviousTouched(e) {
        if( typeof previous_touched != 'undefined' && previous_touched != null && !previous_touched.is( jQuery(e.target) ) ) {
            previous_touched.data('clicked_once', false);
        }
        previous_touched=jQuery(e.target);
    }
}

これがjfiddleです: http://jsfiddle.net/5FfCF/1/

このソリューションを改善できる場合は、提案を提供してください。うまくいかない場合は、私にもお知らせください。ここに投稿して、改善のための提案を得たり、アイデアを公開したりして、他の人が利益を得られるようにします。

これまでの私のテストの結果は次のとおりです。

  1. 主要な5ブラウザー上のWindows 7:機能します。
  2. デフォルトのブラウザのAndroidタブレット:機能します。
  3. IE and Chrome:on-works on the touch-screen with Windows 7 laptop:Sort-of-works。マシンは、両方のブラウザーのデスクトップバージョンなので、「touchstart」イベントはトリガーされません。タッチスクリーンとブラウザーの間のどこかで、タッチがマウスイベントに変換されています。ただし、マウスはこのデバイスの取り外しできない部分なので、タブレットのように動作するようにしたいのですが、まだ利用できるテクノロジがないようです。
  4. iOS iPad:これは期待どおりに機能しましたbefore上記のJavaScriptを書きました。 iOSがこのホバー/クリックマジックの一部を舞台裏で実行しているようです。チームメンバーに、JavaScriptがiOSの機能に違反していないかどうかを確認してもらいます。回答が得られたら、この投稿を編集します。

その他の注意事項:

  1. これは、デスクトップおよびタブレットサイトのメニューのみです。モバイルサイトには、クリックベースの別のメニューがあります。このソリューションを電話サイズのデバイスに使用することはお勧めしません。
15
JoshuaD

Piddle Diddle Fiddle:)


Fiddle Embedded Demo(最も簡単にアクセスできるように電話で使用)


このテキストの壁を読む前に、フィドルをチェックして、それが探しているものであることを確認してください。電話でもテストしました(Androidでテストし、問題はありませんでした)。

携帯電話用の完全に別個のコードセットがある場合、本当に心配する必要はありません。タッチ対ホバーイベントへの適応は、iOSデバイスでは特に注意が必要です。しかし、タッチイベントに変換されたさまざまなマウスイベントをキャプチャすることで、これを克服することができました。

あなたの特定のケースでは、これを3つの間で大きく異ならせたいので、初期のスクリプトを実行して画面サイズを取得し、それが### px x ### pxより小さい場合は、handheldまたはmobileまたはbodyへの何でも。あとは、touchキャプチャコードを$('.mobile .nav')に割り当て、hoverイベントをPCに割り当てる別のコードを用意するだけです。

タブレットの場合、あなたにとってより重要なものを決定する必要があります-各メニューのルートメニュー項目を使用してクリックしてナビゲートする機能、またはサブメニュー項目のクリックのみを許可する(これにより、 .mobileクラスをbodyに)。

モバイルとデスクトップの両方で使用できるコードを次に示します。

jQuery:

jQuery(document).ready(function () {
    $('.nav').on('click mousedown mouseup touchstart touchmove', 'a.has_children', function () {
        if ( $(this).next('ul').hasClass('open') && !$(this).parents('ul').hasClass('open')) {
            $('.open').removeClass('open');
            return false;
        }
        $('.open').not($(this).parents('ul')).removeClass('open');
        $(this).next('ul').addClass('open');
        return false;
    });
    $(document).on('click', ':not(.has_children, .has_children *)', function() {        
        if( $('.open').length > 0 ) {
            $('.open').removeClass('open');
            return false;
        }
    });
});

通常、これから行うようにすべてのHTMLをコピーするわけではありませんが、この特定のインスタンスでは、inline-blockホワイトスペースを避けるために、ここにあるとおりに正確に取得する必要がありますグリッチ。私のフィドルをオリジナルと比較して、各リンクをホバー/クリックする方がはるかに簡単であることを確認してください。

HTML:

<div class="header-nav-menu">
    <ul class="nav">
        <li><a href="http://www.google.com">One</a></li><li>
        <a class="has_children" href="http://www.google.com">Two</a>
            <ul>
                <li><a href="http://www.google.com">2A</a></li><li>
                <a href="http://www.google.com">2B</a>

                </li>
                <li><a href="http://www.google.com">2C</a>

                </li>
            </ul>
        </li><li>
        <a class="has_children" href="http://www.google.com">Three</a>
            <ul>
                <li><a href="http://www.google.com">3A</a>

                </li>
                <li> <a class="has_children" href="http://www.google.com">3B</a>

                    <ul>
                        <li><a href="http://www.google.com">3BI</a>

                        </li>
                        <li><a href="http://www.google.com">3BII</a>

                        </li>
                        <li><a href="http://www.google.com">3BIII</a>

                        </li>
                    </ul>
                </li>
                <li><a href="http://www.google.com">3C</a>

                </li>
            </ul>
        </li><li>
        <a href="http://www.google.com">Four</a></li><li>
        <a href="http://www.google.com">Five</a></li>
    </ul>
</div>

CSSには触れなかったので、Fiddle)はそのままにしておきます。これがあなたの役に立つことを願っています。

13
Deryck