在滚动期间粘滞侧边栏闪烁

时间:2017-02-05 10:00:48

标签: javascript jquery html css3

我创建了这个侧边栏,当div的底部到达它的底部时它会粘住。但是,当我滚动时,它似乎闪烁。你能帮我做错吗?

HTML

<div id="header"></div>
<div id="stickymain">
    <div class="side" id="stickyside">
      <p>
        This is the best we could do and there's nothing more one could expect from here to carry from onwards. I think there's nothing better too.
      </p>
      <p>
        This is the best we could do and there's nothing more one could expect from here to carry from onwards. I think there's nothing better too. This is the best we could do and there's nothing more one could expect from here to carry from onwards. I think there's nothing better too. This is the best we could do and there's nothing more one could expect from here to carry from onwards. I think there's nothing better too.11
      </p>
     </div>
    <div class="main"></div>
    <div class="main"></div>
    <div class="main"></div>
    <div class="main"></div>
    <div class="main"></div>
</div>
<div id="footer"></div>
<script>

CSS

body {
    margin: 0;
    padding: 10px;
}
#header {
    height: 100px;
    margin: 0 0 10px;
    background: red;
}
#content {
    position: relative;
    float: left;
    width: 100%;
    height: auto;
    margin: 0 -110px 0 0;
}
.side {
    float: right;
    width: 100px;
    /* min-height: 500px; */
    margin: 0 0 0 10px;
    background: linear-gradient(red, yellow);
}
.main {
    height: 600px;
    margin: 0 110px 10px 0;
    background: lightgray;
}
#footer {
    clear: both;
    height: 100px;
    background: orange;
}

JS

jQuery(document).ready(function() {
                jQuery.fn.stickyTopBottom = function(){
                    var options = {
                        container: jQuery('#stickymain'),
                        top_offset: 0,
                        bottom_offset: 0
                    };
                    console.log(options);
                    let jQueryel = jQuery(this)

                    let container_top = options.container.offset().top
                    let element_top = jQueryel.offset().top

                    let viewport_height = jQuery(window).height()
                    jQuery(window).on('resize', function(){
                        viewport_height = jQuery(window).height()
                    });



                    let current_translate = 0
                    let last_viewport_top = document.documentElement.scrollTop || document.body.scrollTop
                    jQuery(window).scroll(function(){
                        var viewport_top = document.documentElement.scrollTop || document.body.scrollTop
                        let viewport_bottom = viewport_top + viewport_height
                        let effective_viewport_top = viewport_top + options.top_offset
                        let effective_viewport_bottom = viewport_bottom - options.bottom_offset


                        let element_height = jQueryel.height()

                        let is_scrolling_up = viewport_top < last_viewport_top
                        let element_fits_in_viewport = element_height < viewport_height

                        let new_translation = null
                        if (is_scrolling_up){
                            if (effective_viewport_top < container_top)
                                new_translation = 0
                            else if (effective_viewport_top < element_top + current_translate)
                                new_translation = effective_viewport_top - element_top
                        }else if (element_fits_in_viewport){
                            if (effective_viewport_top > element_top + current_translate)
                                new_translation = effective_viewport_top - element_top

                        }else {
                            let container_bottom = container_top + options.container.height()
                            if (effective_viewport_bottom > container_bottom)
                                new_translation = container_bottom - (element_top + element_height)
                            else if (effective_viewport_bottom > element_top + element_height + current_translate)
                                new_translation = effective_viewport_bottom - (element_top + element_height)
                        }
                        if (new_translation != null){
                            current_translate = new_translation;
                            console.log('i am here at css');

                            jQueryel.css('transform', ('translate(0, '+current_translate+'px)'));
                        }
                        last_viewport_top = viewport_top
                    });
                }
                jQuery('#stickyside').stickyTopBottom();
            });

除了滚动时闪烁的问题,其他一切都按照我想要的方式工作。我在Mac上使用Chrome,Firefox和Safari。

CodePen Demo

1 个答案:

答案 0 :(得分:0)

您可以使用css属性来帮助您,而不是仅使用javascript来完成所有工作。

您可以在到达视口的某个点时更改侧栏的位置属性:

$(window).scroll(function() {
    var sTop = $(this).scrollTop();
    var footerTop = $('#footer').offset().top;
    var sideHeight = $('.side').height();
    var headerHeight = $('#header').height();

    if(sTop > headerHeight + (sideHeight/2)) {
      $('.side').css({
        position:'fixed',
        bottom:'10px'
      });
    } else {
      $('.side').css({
        position:'absolute',
        bottom:'inherit'
      });
    }
});

请参阅此PEN

我希望这个没关系! :)