jQuery setTimeout 的反吹

Blowback on jQuery setTimeout

我尝试在 if 查询中使用超时函数,更具体地说是在滚动函数中。

<script>
$(window).scroll(function() {    
    var scroll = $(window).scrollTop();
    if (scroll >= 400) {
     setTimeout(function() {
        $(".stickfullsize").addClass("hide");
}, 1000);
    } else {
        $(".stickfullsize").removeClass("hide");
    }
});
</script>

一开始,似乎一切正常,但他在删除后将 class "hide" 放回原处。 我已经尝试了在 Whosebug 上看到的几个选项,但对我没有任何帮助。我认为问题是,滚动时该功能在settimeout中不断运行,但我不知道如何处理。

我想达到的目标: 在从顶部滚动 >=400 后将 class 添加到具有设置延迟的 div 并在滚动 <400 到页面顶部时将其删除。

感谢您的帮助

你可能 运行 遇到了麻烦,因为当你越过边界时,你可能会在计时器未完成时删除 class(稍后会添加它)和其他类似的交叉 -说话。

为避免这种情况,请仅在尚未添加计时器时添加它,并在滚动条到达 < 400 时将其删除。

$(window).scroll(function() {
    var scroll = $(window).scrollTop();
    var stickfullsize = $(".stickfullsize");

    if (scroll >= 400) {
        // Only schedule it if it's not scheduled yet and doesn't have the class
        if (!scrollTimer && !stickfullsize.hasClass("hide")) {
            scrollTimer = setTimeout(function() {
                stickfullsize.addClass("hide");
                scrollTimer = 0;
            }, 1000);
        }
    } else {
        // Clear it if it's set
        if (scrollTimer) {
            clearTimeout(scrollTimer);
            scrollTimer = 0;
        }
        stickfullsize.removeClass("hide");
    }
});

实例(使用 >= 100 而不是 >= 400):

for (var n = 0; n < 100; ++n) {
    $("<div>").text("Div " + n).appendTo(document.body);
}
$("div:eq(21)").addClass("stickfullsize");
var timerSpan = $(".timer");
var scrollSpan = $(".scrolltop");

var scrollTimer = 0;

function updateStatus() {
    timerSpan.text(
        (scrollTimer ? "pending" : "not pending") +
        ($(".stickfullsize").hasClass("hide") ? " has class" : "")
    );
}

$(window).scroll(function() {
    var scroll = $(window).scrollTop();
    var stickfullsize = $(".stickfullsize");
    scrollSpan.text(String(scroll));
    if (scroll >= 100) {
        // Only schedule it if it's not scheduled yet
        if (!scrollTimer && !stickfullsize.hasClass("hide")) {
            scrollTimer = setTimeout(function() {
                stickfullsize.addClass("hide");
                scrollTimer = 0;
                updateStatus();
            }, 1000);
        }
    } else {
        // Clear it if it's set
        if (scrollTimer) {
            clearTimeout(scrollTimer);
            scrollTimer = 0;
        }
        stickfullsize.removeClass("hide");
    }
    updateStatus();
});
html {
    box-sizing: border-box;
    font-family: sans-serif;
}
*, *:before, *:after {
    box-sizing: inherit;
}
.hide {
    font-weight: bold;
    color: blue;
}
.status {
    position: fixed;
    height: 1em;
    border-top: 1px solid black;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: white;
}
<div class="status">
  <span class="scrolltop">0</span>
  <span class="timer"></span>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>