私が設計したWebサイトは、:hoverにサブメニューを表示するナビゲーションメニューを使用しています。最初のサイトはレスポンシブデザインを使用していませんでした。デスクトップサイトのみをターゲットにしています。現在、レスポンシブデザイン手法を使用して、モバイルデバイスやタブレットをターゲットにしています。その多くは、マウスベースではなくタッチベースです。
私が直面していた大きな問題(そして他の多くの人々も直面しているようです)は、ホバーベースのナビゲーションメニューでした:マウス環境ではうまく機能しますが、タッチデバイスでは、ホバーをトリガーする確実な方法がなく、使いにくいページ。
目標はこれです:
私のチームは、マウスベースのマシンでのホバー効果を犠牲にするつもりはありません。彼らはそれを好み、すべてのデバイスに基づいてメニューをクリックさせたくありません。これに同意する。
ネットを見回した後、自分の問題に対する単一の解決策を見つけることができませんでした。それらのいくつかを組み合わせて、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/
このソリューションを改善できる場合は、提案を提供してください。うまくいかない場合は、私にもお知らせください。ここに投稿して、改善のための提案を得たり、アイデアを公開したりして、他の人が利益を得られるようにします。
これまでの私のテストの結果は次のとおりです。
その他の注意事項:
このテキストの壁を読む前に、フィドルをチェックして、それが探しているものであることを確認してください。電話でもテストしました(Androidでテストし、問題はありませんでした)。
携帯電話用の完全に別個のコードセットがある場合、本当に心配する必要はありません。タッチ対ホバーイベントへの適応は、iOSデバイスでは特に注意が必要です。しかし、タッチイベントに変換されたさまざまなマウスイベントをキャプチャすることで、これを克服することができました。
あなたの特定のケースでは、これを3つの間で大きく異ならせたいので、初期のスクリプトを実行して画面サイズを取得し、それが### px x ### px
より小さい場合は、handheld
またはmobile
またはbody
への何でも。あとは、touch
キャプチャコードを$('.mobile .nav')
に割り当て、hover
イベントをPCに割り当てる別のコードを用意するだけです。
タブレットの場合、あなたにとってより重要なものを決定する必要があります-各メニューのルートメニュー項目を使用してクリックしてナビゲートする機能、またはサブメニュー項目のクリックのみを許可する(これにより、 .mobile
クラスをbody
に)。
モバイルとデスクトップの両方で使用できるコードを次に示します。
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
ホワイトスペースを避けるために、ここにあるとおりに正確に取得する必要がありますグリッチ。私のフィドルをオリジナルと比較して、各リンクをホバー/クリックする方がはるかに簡単であることを確認してください。
<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)はそのままにしておきます。これがあなたの役に立つことを願っています。