【问题标题】:mouseenter mouseleave not working the way I think it shouldmouseenter mouseleave 没有按我认为应该的方式工作
【发布时间】:2012-08-08 22:28:01
【问题描述】:

我对 jQuery 比较陌生,我似乎被这个 mouseenter/mouseleave 问题困住了。我想设置一个菜单,当页面不在顶部时“隐藏”,这似乎工作正常,当它被隐藏时我想这样做,所以当用户将鼠标悬停在它上面时,类切换和菜单回来了。但是,当它滚动回顶部时,我不希望这样。当页面首次加载(在 Firefox 和 chrome 中)并且我还没有滚动时,它工作正常,但是在向下滚动并返回顶部后,菜单将隐藏在 mouseleave 上。

这是我当前代码设置的jsFiddle

我一直在尝试解决这个问题,并尝试了其他一些方法。

我试过像这样使用悬停

$("#access").hover(function() {
            $(this).removeClass("scroll").addClass("normal");
        }, function() {
            $(this).removeClass("normal").addClass("scroll");
        });

但这和我现在的代码做的一样。

我尝试的其他一些方法是将 b 变量传递给另一个函数,创建一个单独的 div 并跟踪它的位置以确定是否使用 mouseenter/mouseleave,最后绑定它们,但这些都没有似乎按我想的那样工作。

我想不出其他可以尝试的方法,所以我不确定是我做错了什么,还是根本不可能像这样完成。

这是我的第一个问题,我试图包含尽可能多的信息,希望这是足够的信息。

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    试试这个

    $(document).ready(function() {
        $(window).scroll(function() {
            var b = $(window).scrollTop();
            $("#access").toggleClass("normal", b == 0)
            $("#access").toggleClass("scroll", b > 0)
        });
        $("#access").hover(function() {           
            if($(window).scrollTop() > 0){
                $("#access").toggleClass("normal scroll");
            }
        });
    });​
    

    http://jsfiddle.net/bJquD/6/

    【讨论】:

      【解决方案2】:

      您没有考虑页面的滚动状态,因此无论页面是否滚动,mouseenter/mouseleave 事件都会重置类名而不考虑。可以预见的是,这与您想要的并不相符。

      对此的明显解决方案是使用全局变量(尽管在 jQuery 文档就绪的范围内)来跟踪它,然后在 hover() 函数中检查它,导致以下结果:

      var scrolled = false;
      
      $(window).scroll(
          function(){
              var b = $(window).scrollTop();
              if (b == 0) {
                  $('#access').removeClass('scroll').addClass('normal');
                  scrolled = false;
              }
              else if (b > 0) {
                  $('#access').removeClass('normal').addClass('scroll');
                  scrolled = true;
              }
          });
      
      $('#access').hover(
          function(){
              if (scrolled) {
                  // window scrolled, hence access class should be 'scroll'
                  $('#access').removeClass('scroll').addClass('normal');
              }
          },
          function(){
              if (scrolled) {
                  // window scrolled, hence access class should be 'normal' (from mouseenter)
                  $('#access').removeClass('normal').addClass('scroll');
              }
          });​
      

      JS Fiddle demo.

      这样做的结果是,如果页面未滚动,mouseenter/mouseleave 事件什么也不做(因为它们不应该这样做,在这种情况下,normal 类名是正确的),而如果页面 滚动了,他们删除了 mouseenter 上的滚动类名并在 mouseleave 上恢复它。

      【讨论】:

      • 我没想过要设置这样的布尔变量。感谢您的帮助。
      • @Blake:wirey 答案看起来很流畅,没有使用全局范围的变量,很好很简短。不必使用全局范围的变量应该始终是首选。
      【解决方案3】:

      是的,您正在向该元素添加一堆事件处理程序,这最终会大大降低页面速度。你想避免这样做。或者,您可以绑定事件,然后在滚动到页面顶部时将其删除。最好的方法是使用下面的代码。

      $(document).ready(function() {
          $(window).scroll(function() {
              if ($(this).scrollTop() > 0) {
                  $("#access").removeClass("normal").addClass("scroll").on('mouseenter', function() {
                      $(this).removeClass("scroll").addClass("normal");
                  }).on('mouseleave', function() {
                      $(this).removeClass("normal").addClass("scroll");
                  });
              } else {
                  $("#access").removeClass("scroll").addClass("normal").off('mouseenter mouseleave');
              }
          });
      });​
      

      你也可以试试here

      希望能帮到你:)

      【讨论】:

        【解决方案4】:

        在这里,您只需添加变量 isOnTop,mouseenter 和 mouseleave 处理程序在执行任何操作之前都会对其进行检查

        $(document).ready(function() {
        var isOnTop=1;
            $(window).scroll(function() {
                var b = $(window).scrollTop();
        
                if (b > 0) {
                    isOnTop=0;            
                    $("#access").removeClass("normal").addClass("scroll");
                }
        
                else if (b == 0) {
                    isOnTop=1;
                    $("#access").removeClass("scroll").addClass("normal");
                }
        
            });
        
            $("#access").mouseenter(function() {
                if(isOnTop){return;}
                $(this).removeClass("scroll").addClass("normal");
            });
        
            $("#access").mouseleave(function() {
                if(isOnTop){return;}
                $(this).removeClass("normal").addClass("scroll");
            });
        });​
        

        【讨论】:

        • 每次执行showMenu()hideMenu() 时,都会绑定一个新的处理程序。我不认为你真的想这样做
        猜你喜欢
        • 1970-01-01
        • 2013-08-09
        • 2015-04-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-12
        相关资源
        最近更新 更多