【问题标题】:jQuery hover menu not disappearingjQuery悬停菜单不会消失
【发布时间】:2011-02-06 14:02:13
【问题描述】:

编辑:在此处查看实际操作:http://jsbin.com/emobi/5 -- 那是使用 mouseenter/mouseleave。

我有一个使用一些嵌套 UL 的基本菜单,我认为这是非常标准的。当从“根”菜单悬停在 LI 上时,我希望显示该 LI 中的 UL。将鼠标移开或移至另一个 LI,它会显示该子菜单。向下移动到子菜单,当您将鼠标悬停在每个元素上时它会保持不变。我让它使用一个简单的 jQuery.hover() 集,但后来我遇到了问题。在页面上时,“根”菜单项被赋予一个“当前页面”类,如果该类存在,我希望它在鼠标移出后静态显示该子菜单。

希望我解释得足够好。我只是将一个变量扔到悬停函数中,所以在鼠标悬停时它在当前页面的子菜单上运行了一个 .show() 。简单。除了当我在子菜单的各个 LI 之间移动鼠标时,它会变回当前页面的子菜单。所以我尝试在这里添加一个基于another question 的计时器元素。这让事情变得更糟——现在子菜单并没有消失。

这是我的 CSS、标记和 JS ......我到底是如何让它正常工作的?

标记:

<div id="menu">
<div id="navbar">
    <ul id="firstmenu">
        <li>
            <a href="http://localhost/site/pageone">page one</a>
            <ul class="submenu">
                <li><a href="http://localhost/site/pageone/subone">subone</a></li>
                <li><a href="http://localhost/site/pageone/subtwo">subtwo</a></li>
                <li><a href="http://localhost/site/pageone/subthree">subthree</a></li>
                <li><a href="http://localhost/site/pageone/subfour">subfour</a></li>
                <li><a href="http://localhost/site/pageone/subfive">subfive</a></li>
            </ul>
        </li>

        <li>
            <a href="http://localhost/site/pagetwo">barely there</a>
            <ul class="submenu">
                <li><a href="http://localhost/site/pageone/subone">subone</a></li>
                <li><a href="http://localhost/site/pageone/subtwo">subtwo</a></li>
                <li><a href="http://localhost/site/pageone/subthree">subthree</a></li>
                <li><a href="http://localhost/site/pageone/subfour">subfour</a></li>
                <li><a href="http://localhost/site/pageone/subfive">subfive</a></li>
            </ul>
        </li>
        <li class="current-page">
            <a href="http://localhost/site/pagetwo">kith & kin</a>
            <ul class="submenu">
                <li><a href="http://localhost/site/pageone/subone">subone</a></li>
                <li><a href="http://localhost/site/pageone/subtwo">subtwo</a></li>
                <li><a href="http://localhost/site/pageone/subthree">subthree</a></li>
                <li><a href="http://localhost/site/pageone/subfour">subfour</a></li>
                <li><a href="http://localhost/site/pageone/subfive">subfive</a></li>
            </ul>

        </li>
        <li>
            <a href="http://localhost/site/pagethree">focal point</a>
            <ul class="submenu">
                <li><a href="http://localhost/site/pageone/subone">subone</a></li>
                <li><a href="http://localhost/site/pageone/subtwo">subtwo</a></li>
                <li><a href="http://localhost/site/pageone/subthree">subthree</a></li>
                <li><a href="http://localhost/site/pageone/subfour">subfour</a></li>
                <li><a href="http://localhost/site/pageone/subfive">subfive</a></li>
            </ul>
        </li>
        <li>
            <a href="http://localhost/site/pagefour">products</a>
            <ul class="submenu">
                <li><a href="http://localhost/site/pageone/subone">subone</a></li>
                <li><a href="http://localhost/site/pageone/subtwo">subtwo</a></li>
                <li><a href="http://localhost/site/pageone/subthree">subthree</a></li>
                <li><a href="http://localhost/site/pageone/subfour">subfour</a></li>
                <li><a href="http://localhost/site/pageone/subfive">subfive</a></li>
            </ul>
        </li>
        <li>
            <a href="http://localhost/site/pagefive">clients</a>
        </li>

    </ul>
</div></div>

这是 CSS:

    #navbar {
     margin: 0;
     padding: 0;
     border: 0;
     text-align: center;
 }

 #firstmenu {
    margin: 6px auto 0 auto;
    font-size: 16px;
    list-style-type: none;
    letter-spacing: -1px;
 }

 #firstmenu li {
    display: inline;
    position:relative;
    overflow: hidden;
    text-align: center;
    margin-right: 10px;
    padding: 5px 15px;
 }

 #firstmenu a {
    text-decoration: none;
    outline: none;
    color: black;
    font-weight: 700;
    width: 75px;
    cursor: pointer;
 }

.current-page {
     color: white;
     background: url(../images/down_arrow.png) bottom center no-repeat;

}
.current-page a {
     color: white;
     border-bottom: 1px solid black;
}

#firstmenu .current-page a {
    color: white;
}

#firstmenu li.hover {
     color: white;
     background: url(../images/down_arrow.png) bottom center no-repeat;
}
#firstmenu li.hover a {
     color: white;
     border-bottom: 1px solid black;
}

#firstmenu li ul li.hover {
     color: white;
     background: none;
}
#firstmenu li ul li.hover a {
     color: white;
     border-bottom: none;
     text-decoration: underline;
}

#firstmenu li ul {
    width: 900px;
     color: white;
     font-size: .8em;
     margin-top: 3px;
     padding: 5px;
     position: absolute;
     display: none;
}

#firstmenu li ul li {
    list-style: none;
    display: inline;
    width: auto;
}

#firstmenu li ul li a {
    color: white;
    font-weight: normal;
    border: none;
}

.sub-current-page {
    font-weight: bold;
    text-decoration: underline;
}

#firstmenu li ul li.sub-current-page a {
    font-weight: bold;
}

最后,我的完全不工作的 JS(当然是在 $(document).ready() 中):

// Initialize some variables
    var hideSubmenuTimer = null;
    var current_page;
$('.current-page ul:first').show();

    // Prep the menu
    $('#firstmenu li').hover(function() {
        // Clear the timeout if it exists
        if(hideSubmenuTimer) { clearTimeout(hideSubmenuTimer); }

        // Check if there's a current-page class set
        if($('li.current-page').length > 0) {
            current_page = $('li.current-page');
        } else {
            current_page = false;
        }

        // If there's a current-page class, hide it
        if(current_page) { current_page.children('ul:first').hide(); }

        // Show the new submenu
        $(this).addClass('hover').children('ul:first').show();

    }, function(){
        // Just in case
        var self = this;
        // Clear the timeout if it exists
        if(hideSubmenuTimer) { clearTimeout(hideSubmenuTimer); }

        // Check if there's a current-page class set
        if($('li.current-page').length > 0) {
            current_page = $('li.current-page');
        } else {
            current_page = false;
        }

        // Set a timeout on hiding the submenu
        hideSubmenuTimer = setTimeout(function() {
            // Hide the old submenu
            $(self).removeClass('hover').children('ul').hide();

            // If there's a current-page class, show it
            if(current_page) { current_page.children('ul:first').show(); current_page.css('color', 'white'); }
        }, 500);
    });

那我做错了什么?

作为旁注,我使用 $('.current-page ul:first').show() 因为如果我在 CSS 中为 .current-page 提供任何“显示”设置,它会真正定位它页面上很奇怪。

【问题讨论】:

    标签: jquery css hover menu


    【解决方案1】:

    答案是脚本试图在子菜单的 LI 上运行 hover/mouseenter/whatever 功能。通过为每个根菜单 LI 提供自己的类,它现在可以工作了。这样它就不会调用子菜单 LI 上的函数。这是完成的功能:

    $('#firstmenu .root-item').mouseenter(function() {
        $(this).addClass('hover').children('ul:first').show();
        if($('.current-page').length > 0) {
            $('.current-page').children('ul:first').hide();
        }
    }).mouseleave(function() {
        $(this).removeClass('hover').children('ul').hide();
        if($('.current-page').length > 0) {
            $('.current-page').children('ul:first').show();
        }
    });
    

    【讨论】:

      【解决方案2】:

      你为什么要搞乱超时?你应该只是.toggle()吗?

      【讨论】:

      • .toggle() 用于点击事件;我希望鼠标悬停时菜单可以工作。
      • 是的,您可以在function(){...}function(){...} 的元素上.toggle() 一个类。
      【解决方案3】:

      我将它改写为不使用悬停,而是使用鼠标悬停和鼠标悬停。 不知道你是否喜欢它,但这里是代码:

      $(document).ready(function(){
                $(".submenu").hide();
                $("li").mouseover(function(){
                  $(this).find('.submenu').show();
                  });
                $("li").mouseout(function(){
                  $(this).find('.submenu').hide();
                  })
      });
      

      编辑:我花时间查看了您的代码并发现了有问题的行:

      #firstmenu li {
          display: inline;
      

      由于嵌套列表位于第一个菜单 div 中,这也适用于它们。无法放置内联的嵌套列表,因此不再将其作为其 dom 父级的子级放置在布局引擎中。结果是鼠标悬停在子菜单上仍被视为鼠标悬停在其 dom 父级上(由于冒泡),但在列表项之间,您将不再将鼠标悬停在 dom 父级上(就像在原始设计中一样)。你需要重新考虑你的布局设计,因为现在它破坏了布局引擎。

      您可能还应该重新考虑将列表用作表格...

      【讨论】:

      • mouseovermouseout 将向孩子们开火,隐藏他们......你会想要 mouseentermouseleave 在这里。
      • 其实当它进入子元素时,会触发子元素li上的mouseover,它会涓涓细流到原来的li,并重新显示它们。虽然你是对的,mouseentermouseleave 会更干净
      • @tzenes - 前一个元素的mouseout 事件在下一个元素的mouseover 之前触发,想想focusblur 是如何工作的,同样的情况。所以子元素在mouseover 触发之前被隐藏,但它不可见,它只是被隐藏了,所以它永远不会触发。
      • 这仍然是我遇到的第一个问题。在子菜单里水平滑动光标时,菜单消失,离开一里时返回到当前页面菜单。这是实际问题的粘贴箱:pastebin.com/ZTZipdGG
      • @Nick - 在这里试试:jsbin.com/ejuwe 你遇到了并发问题。当鼠标移动被更新时,它会查看它所在的 dom 元素,然后它会看到这不是同一个元素,并且 mouseout 被添加到事件队列中,然后它看到这是一个新元素并将 mouseover 添加到事件队列。由于它在函数开头对 dom 元素进行采样,因此即使将其删除,它仍然认为它超过了子 li
      猜你喜欢
      • 1970-01-01
      • 2014-08-30
      • 2013-02-25
      • 1970-01-01
      • 1970-01-01
      • 2013-08-09
      • 1970-01-01
      • 2021-01-22
      • 1970-01-01
      相关资源
      最近更新 更多