在触摸屏上处理悬停事件

Jos*_*uaD 15 html javascript css jquery responsive-design

我设计的网站使用导航菜单显示子菜单:悬停.初始站点没有使用任何响应式设计:它仅针对桌面环境.我现在使用响应式设计技术来定位移动设备和平板电脑,其中许多是基于触摸而不是基于鼠标.

我面临的一个大问题(以及许多其他人似乎也面临过)是基于悬停的导航菜单:它在鼠标环境中运行良好,但在触摸设备上,没有可靠的方法来触发悬停,该页面难以使用.

目标是这样的:

  1. 当菜单被鼠标悬停时,显示子菜单.
  2. 使用鼠标单击菜单时,请打开锚标记的链接.
  3. 第一次通过触摸单击菜单时,显示子菜单.
  4. 第二次通过触摸单击菜单,打开锚标记的链接.
  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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个jfiddle:http://jsfiddle.net/5FfCF/1/

如果可以改进此解决方案,请提供任何建议.如果您发现它不适合您,请告诉我.我在这里发布它是为了试图获得任何改进建议并发布这个想法,以便其他人可以从中受益.

以下是我目前测试的结果:

  1. 主要5个浏览器上的Windows 7:有效.
  2. 默认浏览器上的Android平板电脑:有效.
  3. IE和Chrome上带触摸屏的Windows 7笔记本电脑:工作类型.该机器正在运行两种浏览器的桌面版本,因此它不会触发"touchstart"事件.在触摸屏和浏览器之间的某处,有些东西正在将触摸转换为鼠标事件.但是,由于鼠标是此设备的不可拆卸部分,我不认为这是一个失败.如果它像平板电脑一样工作,我想它,但似乎还没有可用的技术.
  4. iOS iPad:我编写上述javascript 之前,这可以正常工作.似乎ios在幕后为我们做了一些悬停/点击魔术.我有一个团队成员检查我的javascript是否破坏了iOS功能,我会在得到答案后编辑这篇文章.

其他说明:

  1. 这只是桌面和平板电脑网站的菜单.移动网站有一个不同的基于点击的菜单.我不建议将此解决方案用于手机大小的设备.

Der*_*yck 13

Piddle Diddle小提琴:)


Fiddle Embedded Demo(与手机配合使用,便于访问)


在您阅读这一文字墙之前,请查看小提琴并确保它是您正在寻找的内容.也在手机上测试(我在我的Android上测试过没有问题).

如果你有一套完全独立的手机代码,那么你真的无需担心.在iOS设备上适应触摸与悬停事件尤其棘手.但我能够通过捕获一系列转化为触摸事件的鼠标事件来克服这个问题.

为了您的具体情况,因为你想这是三者之间如此不同,我建议运行的早期脚本来获取屏幕大小,如果它不到### px x ### px,一个名为类添加handheldmobile或什么来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;
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

通常情况下,我不会复制所有的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>
Run Code Online (Sandbox Code Playgroud)

很确定我甚至没有碰过CSS所以我现在就把它留在小提琴里.希望这能帮到你.