简体   繁体   English

jQuery-ScrollTop事件触发动画

[英]jQuery - ScrollTop event to trigger animation

I am trying to achieve a scrollTop effect when I scroll under #header. 我在#header下滚动时试图达到scrollTop效果。 Thing is, it keeps running when I am scrolling, so it's executing a hacky effect. 事实是,当我滚动时,它一直在运行,因此它正在执行骇人的效果。 How can I make it run without lagging? 如何使它运行而不会滞后?

$(window).scroll(function(){
var start = 0;
var position = start + $('body').scrollTop();
var header = $('#header').height();
var breakpoint = parseInt(header)-100;
if( position > breakpoint ) {
    $('.nav-bar-bg').stop().delay(0).animate({
        top: 0
    }, 200);
    $('.nav-bar').stop().delay(0).animate({
        marginTop: -20
    });
    $('.logo a.first').stop().delay(0).animate({
        marginTop: -60
    });
} if ( position < breakpoint ) {
    $('.nav-bar-bg').stop().delay(0).animate({
        top: -100
    }, 200);
    $('.nav-bar').stop().delay(0).animate({
        marginTop: 0
    });
    $('.logo a.first').stop().delay(0).animate({
        marginTop: 0
    });
}
});

That's funny, I was just running into this problem today with a resize handler. 太好笑了,我今天刚遇到一个带有大小调整处理程序的问题。 What you should do is add a timeOut that will stop your function from continuously executing until the user has finished scrolling. 您应该做的是添加一个超时,该超时将停止函数继续执行,直到用户完成滚动为止。 Something like the following: 类似于以下内容:

//concept derived from Дмитрий Гапонов
var scrollFunction;
$(window).on('scroll', function() {
    clearTimeout(resized);
    scrollFunction = setTimeout(setHtmlScale, 100, true);
});

You can experiment with smaller values for the timeOut; 您可以尝试使用较小的timeOut值; 100 is pretty conservative. 100是相当保守的。

I think that should work for you. 我认为这应该为您工作。 Let me know if it doesn't. 让我知道是否可以。

Here is a fairly long answer to your question. 这是您问题的相当长的答案。 I'm going to provide two variants. 我将提供两个变体。 The first is a jQuery only one similar to what you posted. 第一个是jQuery,只有一个与您发布的类似。

jQuery/JavaScript solution jQuery / JavaScript解决方案

The main things I changed were I'm caching all of the jQuery selector queries up front so that those (relatively) expensive operations only run once instead of every time the scroll event fires. 我更改的主要内容是预先缓存了所有jQuery选择器查询,以便那些(相对)昂贵的操作仅运行一次,而不是每次scroll事件触发时都运行一次。 I also added some simple debouncing so that the scrollFunc doesn't constantly fire. 我还添加了一些简单的反跳功能 ,以使scrollFunc不会不断触发。

// Perform and cache all of the selectors first so that it doesn't run on every `scroll` event
var $body = $('body');
var $header = $('#header');
var $navBarBg = $('.nav-bar-bg');
var $navBar = $('.nav-bar');
var $logo = $('.logo a.first');

var scrollFunc = function(){
    var start = 0;
    var position = start + $body.scrollTop();
    var header = $header.height();
    var breakpoint = header - 100; // No need to use parseInt. It would just introduce bugs.
    if( position > breakpoint ) {
        $navBarBg.stop().delay(0).animate({
            top: 0
        }, 200);
        $navBar.stop().delay(0).animate({
            marginTop: -20
        });
        $logo.stop().delay(0).animate({
            marginTop: -60
        });
    } else { // No need to do additional comparison
        $navBarBg).stop().delay(0).animate({
            top: -100
        }, 200);
        $navBar.stop().delay(0).animate({
            marginTop: 0
        });
        $logo.stop().delay(0).animate({
            marginTop: 0
        });
    }
};

$(window).scroll(function(){
    // Debounce requests, so that it doesn't fire everytime the scroll event fires (which is a lot)
    if (scrollFunc.timeout) {
        clearTimeout(scrollFunc.timeout);
    }
    scrollFunc.timeout = setTimeout(scrollFunc, 100);
});

CSS/jQuery solution CSS / jQuery解决方案

In this example I'm adding and removing CSS classes instead of altering inline styling of the elements. 在此示例中,我将添加和删除CSS类,而不是更改元素的内联样式。 This is the preferred way of doing it IMO as you keep the styling stuff in CSS and out of JS. 这是IMO的首选方式,因为您将样式内容保留在CSS中而不包含在JS中。 Also, CSS animations usually perform better / more smoothly. 而且,CSS动画通常表现更好/更流畅。

// JavaScript
// Perform and cache all of the selectors first so that it doesn't run on every `scroll` event
var $body = $('body');
var $header = $('#header');

var scrollFunc = function(){
    var start = 0;
    var position = start + $body.scrollTop();
    var header = $header.height();
    var breakpoint = header - 100; // No need to use parseInt. It would just introduce bugs.
    if( position > breakpoint ) {
        $body.addClass('underHeader');
    } else { // No need to do additional comparison
        $body.removeClass('underHeader');
    }
};

$(window).scroll(function(){
    // Debounce requests, so that it doesn't fire everytime the scroll event fires (which is a lot)
    if (scrollFunc.timeout) {
        clearTimeout(scrollFunc.timeout);
    }
    scrollFunc.timeout = setTimeout(scrollFunc, 100);
});

// CSS
.nav-bar-bg, .nav-bar, .logo a.first {
    transition: all 0.5s;
}

.nav-bar-bg {
    top: -100;
}

.nav-bar {
    margin-top: 0;
}

.logo a.first {
    margin-top: 0;
}


.underHeader .nav-bar-bg {
    top: 0;
}

.underHeader .nav-bar {
    margin-top: -20px;
}

.underHeader .logo a.first {
    margin-top: -60px;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM