Search code examples
jquerysafariscrollpositioningcss-position

jquery mixed scrolling problems


My main objective is to have the whole webpage scroll on creation without allowing the projects div to scroll. Then once you scroll an arbitrary amount of pixels, centering the projects div on the window, the only you can scroll is the the projects div. When the main_content div becomes fixed and it's top position gets changed from 0, I am getting 2 problems.

1) The screen blinks if while I'm scrolling my cursor is in the middle of the screen. (I've tried fixing this by adding -webkit-backface-visibility: hidden; to the css sheet, But it still blinks a little)

2) If, while scrolling, your cursor is in the black while and the fixed class is added to main_content, the page jumps up instead of staying put. This isn't happening for me in chrome, just safari.

Photo - http://farm4.staticflickr.com/3793/9293713553_ee3baf8d9d_b.jpg

Here is a fiddle, but it won't produce the error that safari is giving me. http://jsfiddle.net/chongwaldo/6mkDS/

HTML

<!DOCTYPE html>
    <html>
        <head>
            <link href="Scrolling_Test.css" rel="stylesheet">
            <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
            <script type='text/javascript' src='Scrolling_Test.js'></script>
        </head>

        <body>
            <div class="main_content">
                <div class="black top">
                </div>

                <div class="projects">
                    <div class="window project_1">
                    </div>
                    <div class="window project_2">
                    </div>
                    <div class="window project_3">
                    </div>
                </div>

                <div class="black bottom">
                </div>
            </div>
        </body>
    </html>

CSS

html, body {
    margin:0px;
    -webkit-backface-visibility: hidden;
}

div {
    width:100%;
    -webkit-backface-visibility: hidden;
}

.main_content {
    position:absolute;
    top:0;
    left:0;
}

.black {
    background-color:#000;
    height:800px;
}

.fixed {
    position:fixed !important;
    top:0;
    left:0;
}
.scroll {
    overflow:scroll !important;
}

.projects {
    height:700px;
    overflow:hidden;
}

.window {
    height:700px;
}

.project_1 {
    background-color:#addfe7;
}
.project_2 {
    background-color:#b0e8e6;
}
.project_3 {
    background-color:#b9eadd;
}

jQuery

$(document).ready(function() {

    var $window = $(window), // Cache the window object
        stopLine = 550,
        dir = 'down', // direction
        lastScroll = 0;

    $('.window').text(dir);

    // Execute when window scrolls
    $(window).scroll(function(){ // scroll event
        var fromTop = $window.scrollTop();

        $('.window').text(dir);
        $('.window').append('<br/>'+fromTop);

        // Get scrolling direction
        if(fromTop > lastScroll){ dir = 'down'; }
        else { dir = 'up'; }

        // Set new lastScroll value
        lastScroll = fromTop;

        if( dir === 'down' &&
            fromTop >= stopLine){

            $('.main_content').addClass('fixed');
            $('.projects').addClass('scroll');

            $('.fixed').css({
                'top': -stopLine
            });


        } else {

        }

    });

});

Solution

  • The page was jumping because of the code in the scroll event ($(window).scroll(function(){});).

    1. $('.main_content').addClass('fixed'); The 'top' value in the fixed class starts out at 0.
    2. $('.fixed').css({ 'top': -stopLine }); The 'top' value gets changed to the -stopLine value.

    Because both of these pieces of code happen before the next scroll event gets called, the user experience a jump in the window when triggering several scrolling events (continuos scrolling). The page becomes fixed at top:0, then moves to top:-stopLine, all before the next scroll.

    To offset this jump in the top I just added a scrollTop() to the page so that the window gets evened out before the scrolling continues.

    This, $('html, body').scrollTop( stopLine ), with the added -webkit-backface-visibility: hidden to the css stops the blinking and the jumping.

    jsfiddle - http://jsfiddle.net/chongwaldo/mmdDD/

    Added JQuery

     // Block must stay in order
     //###################################
     /*(1)*/$('.main_content').addClass('fixed');
     /*(2)*/$('.projects').addClass('scroll');
     /*(3)*/$('.fixed').css({
        'top': -stopLine
     });
     /*(4)*/$('html, body').scrollTop(
        stopLine
     );
     //###################################