Bagusa4 Bagusa4 - 2 months ago 11
HTML Question

Sticky Nav flickering like flashing lights

I made the code, to make the nav can be a sticky nav, but the code that I created to make the sticky nav, making the sticky nav blinking, why? Where is the fault?

Here is my code :

;(function($) {

$.fn.tosticky = function(o) {

o = $.extend({

tofixedClass: 'classtofixed',
fixedClass: 'fixedclass',
top: 0,
bottom: 0

}, o);

return this.each(function() {

var $window = $(window),
$this = $(this);

$window.on("scroll", function() {
var fence = $(o.tofixedClass).offset().top;
var scrollTop = $(this).scrollTop();
if(scrollTop > fence) {
$(o.tofixedClass).addClass(o.fixedClass).css({"margin-top":o.top,"margin-bottom":o.bottom});
} else {
$(o.tofixedClass).removeClass(o.fixedClass);
}
});

});
};
})(jQuery);

$(function () {
$(".pagar").tosticky({ // use this to run code in above
tofixedClass: '.pagar',
fixedClass: 'fixed',
top: 0,
bottom: 0
});
});


And here is my code in jsfiddle : Click Here

Answer

This is happening because when your element reaches the top of the window, its distance from the top becomes equal to $(this).scrollTop();, so you'll have to include cases where these are equal, otherwise the other part of the if statement will be true, thus the fixedClass will be removed, then re-added again when you do some scrolling, then the whole thing starts again, hence the flickering.

To correct this, just replace the greater than sign (>) with greater than or equal sign (>=) in your if statement:

if(scrollTop >= fence) {
    $(o.tofixedClass).addClass(o.fixedClass).css({"margin-top":o.top,"margin-bottom":o.bottom});
} else {
    $(o.tofixedClass).removeClass(o.fixedClass);
}

Here is your updated fiddle: http://jsfiddle.net/1wxggpv5/6/

EDIT: following your comment, although this wasn't part of your original question, I understand you want the box to remain where it is, and the whole thing to go back to its original position when you scroll back up.

To do that, you'll have to move #box inside .pagar and move your fence variable out of the on.scroll function as follows:

jQuery (the relevant bits):

return this.each(function() {

    var $window = $(window),
        $this = $(this),   
        fence = $(o.tofixedClass).offset().top;

    $window.on("scroll", function() {
        var scrollTop = $(this).scrollTop();
        if(scrollTop >= fence) {
            $(o.tofixedClass).addClass(o.fixedClass).css({"margin-top":o.top,"margin-bottom":o.bottom});
        } else {
            $(o.tofixedClass).removeClass(o.fixedClass);
        }  
    });
});

HTML:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class = "pagar">
    If you scroll past me, then you'll *NOT* see such as flashing lights flickering, and we now know why :)
    <div id = "box">
        Oh hello! :D
    </div>
</div>
<div class="scroll"></div>

I updated your original fiddle with this code: http://jsfiddle.net/1wxggpv5/19/