Javascript mouseenter Mousele没有按我认为应该的方式工作

Javascript mouseenter Mousele没有按我认为应该的方式工作,javascript,jquery,Javascript,Jquery,我对jQuery比较陌生,我似乎被这个mouseenter/mouseleave问题困扰着。我想设置一个菜单,当页面不在顶部时“隐藏”,这似乎工作正常,当它被隐藏时,我想这样做,当用户将鼠标悬停在它上面时,类切换,菜单返回。但是,我不希望它被卷回顶部。当页面第一次加载(在firefox和chrome中)并且我还没有滚动时,它可以正常工作,但是在向下滚动并返回到顶部之后,菜单将隐藏在mouseleave上 下面是我当前代码设置的一个示例 我已经尝试解决这个问题有一段时间了,并且尝试了其他一些方法

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

下面是我当前代码设置的一个示例

我已经尝试解决这个问题有一段时间了,并且尝试了其他一些方法

我试过像这样使用悬停

$("#access").hover(function() {
            $(this).removeClass("scroll").addClass("normal");
        }, function() {
            $(this).removeClass("normal").addClass("scroll");
        });
但这和我现在的代码是一样的

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

我想不出还有什么可以尝试的,所以我不确定这是不是我做错了什么,或者这是不是不可能做到的


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

您没有考虑页面的滚动状态,因此mouseenter/mouseleave事件是,无论页面是否滚动,都会不加考虑地重置类名。不出意料的是,这与你想要的东西不符

解决这一问题的明显方法是使用一个全局变量(尽管在jQuery文档ready的范围内)来跟踪它,然后在
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');
        }
    });​


这样做的结果是,如果页面被取消滚动,
mouseenter
/
mouseleave
事件什么也不做(因为它们不应该这样做,在这种情况下,
normal
类名是正确的),而如果页面被滚动,它们在
mouseenter
上删除滚动类名,并在
mouseleave
上恢复滚动类名。在这里,您只需添加变量isOnTop,mouseenter和mouseleave处理程序在执行任何操作之前对其进行检查


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

$(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');
        }
    });
});​
你也可以试一试

希望这能帮到你:)

试试这个

$(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");
        }
    });
});​

每次执行
showMenu()
hideMenu()
时,都会绑定一个新的处理程序。我不认为你真的想这么做,我不认为要设置这样的布尔变量。谢谢您的帮助。@Blake:
wirey
答案看起来非常流畅,没有使用全局范围的变量,很好,很短。不必使用全局作用域变量应始终是首选。
$(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");
        }
    });
});​