javascript - 处理触摸屏上的悬停事件

标签 javascript jquery html css responsive-design

关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。












这个问题似乎与 help center 中定义的范围内的编程无关。 .


8年前关闭。







Improve this question




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

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

目标是这样的:

  • 当鼠标悬停菜单时,显示子菜单。
  • 用鼠标单击菜单时,打开 anchor 标记的链接。
  • 第一次通过触摸单击菜单时,显示子菜单。
  • 第二次通过触摸单击菜单时,打开 anchor 标记的链接。
  • 为也连接了鼠标设备的平板电脑无缝切换功能。

  • 我的团队不愿意牺牲基于鼠标的机器上的悬停效果。他们喜欢它,不想让菜单基于所有设备点击。我同意这一点。

    环顾网络后,我找不到任何单一的解决方案来解决我的问题。我将其中一些放在一起,开发了一些在 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/

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

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

  • 其他注意事项:
  • 这只是桌面和平板电脑站点的菜单。移动网站有一个不同的基于点击的菜单。我不建议将此解决方案用于手机大小的设备。
  • 最佳答案

    Piddle Diddle Fiddle :)

    Fiddle Embedded Demo (use with phone for easiest access)

    在阅读这堵文字墙之前,请先检查一下 fiddle 并确保它是您正在寻找的。也在手机上测试(我在我的 Android 上测试过,没有问题)。

    如果您有一套完全独立的手机代码,那么您真的没有什么可担心的。适应触摸与悬停事件在 iOS 设备上特别棘手。但是我能够通过捕获一系列转换为触摸事件的鼠标事件来克服这个问题。

    对于您的特殊情况,由于您希望这三者之间如此不同,我建议您运行早期脚本来获取屏幕尺寸,如果它小于 ### 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。空白故障。将我的 fiddle 与您的原作进行比较,看看悬停/单击每个链接有多容易。

    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 中。希望这对您有所帮助。

    关于javascript - 处理触摸屏上的悬停事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20818863/

    相关文章:

    javascript - 使用带有一些自定义函数的 jquery 验证名称

    javascript - jquery计算同一类不同元素的不同值

    html - <article> 或 <section> 标签之间的混淆。使用哪个?

    javascript - 下载文件不适用于 iframe

    javascript - 在 javascript 中调用方法和字段时避免对象

    java - 在 Struts 2 中将参数从 View 传递到操作

    javascript - 如何将元素推送到 3D 数组 (Javascript)

    javascript - 第二个函数(鼠标移出)的 jQuery 悬停问题

    javascript - 如何将文本放在同时调整大小的调整大小图像上?

    javascript - jQuery 下拉菜单在 IE 和 Webkit 中的行为不同