免费滚动粘贴侧边栏没有jQuery

时间:2015-12-11 00:36:54

标签: javascript sidebar

我试图实现此Stack Overflow问题中概述的内容,没有jQuery依赖:stackoverflow.com/questions/18358816/sticky-sidebar-stick-to-bottom-when-scrolling-down-top-when-scrolling-up

但我并不想劫持这个问题。

基本上,我希望侧边栏中的内容可以独立滚动,但在视口到达滚动时侧边栏内容的任一端时修复。

我的主要绊脚石似乎无法在侧边栏绝对定位时计算elementTop变量,并且在容器的顶部和底部之间设置为全高。

以下完整代码:

var StickySidebar = function(eventie) {

var container, containerTop, containerHeight,  // container
element, elementTop, elementHeight, elStyle,  // element
viewportTop = -1, viewportHeight, documentTop, // viewport
lastViewportTop, scrollingDown, top = false , bottom = false,// sticky vars

scroll = window.requestAnimationFrame ||
         window.webkitRequestAnimationFrame ||
         window.mozRequestAnimationFrame ||
         window.msRequestAnimationFrame ||
         window.oRequestAnimationFrame ||
         function(callback){ window.setTimeout(callback, 1000/60); },

options =  {
    container : document.querySelector('.sidebar-container'),
    element : document.querySelector('.sidebar'),
    sidebarClass : 'sidebar',
    bottomOffset : -15,
    topOffset: 90,
},

_updateValue = function() {
    viewportHeight = window.innerHeight;
},

_offset = function(obj) {    
    var ol = ot = 0;
    if (obj.offsetParent) {
        do {
            ol += obj.offsetLeft;
            ot += obj.offsetTop;
        } while (obj = obj.offsetParent);
    }
    return {
        left: ol,
        top: ot
    };
},


init = function(){
    if(options.element !== null) {

        container = options.container;
        containerTop = offset(container).top;
        containerHeight = container.clientHeight;

        element = options.element;
        elementTop = offset(element).top;
        elementHeight = options.element.clientHeight;

        lastViewportTop = window.scrollY;
        viewportHeight = window.innerHeight;

        eventie.bind(document, "scroll", _loop);
        eventie.bind(window, "resize", _updateValue);

    }
},

_loop = function() {
    if (viewportTop == window.pageYOffset) {
        scroll(_loop);
        return false;
    } else viewportTop = window.pageYOffset;

    _updateValue();

    var viewportBottom, elementTooBig, topOffset;

    elementTop = offset(element).top;

    elementHeight = element.clientHeight;
    containerHeight = container.clientHeight;
    scrollingDown = viewportTop > lastViewportTop;
    elementTooBig = elementHeight > viewportHeight;

    console.log("elementTop : " + elementTop);
    console.log("viewportTop : " + viewportTop);

    if (scrollingDown) {

        if (viewportTop + viewportHeight >= elementTop + elementHeight) {
            element.setAttribute('style','position:fixed; bottom:30px;');
        } else {
            element.setAttribute('style','position:absolute; top:'+ elementTop +'px;'); // issue 1
    }

    if (viewportTop + viewportHeight > containerTop + containerHeight) {
        element.setAttribute('style','position:absolute; bottom:0;');
    }

} else {

    if (viewportTop < containerTop - 60) {
        element.removeAttribute('style');
        return;
    }

    if (viewportTop <= elementTop) {
        element.setAttribute('style','position:fixed; top:90px;');
    } else {
        element.setAttribute('style','position:absolute; top:'+ elementTop +'px;');
        elementTop = viewportTop + elementTop;
    }

}

lastViewportTop = viewportTop;

};


return {
    init: init
};

}(eventie);

我几周来一直试图解决这个问题,这让我感到疯狂。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:5)

如果你只是试图达到预期的结果而不一定是自己创造 - 那么,有许多JavaScript库可以提供这些。

例如,Stickyfill实际上是position: sticky的填充,natively supported only in Firefox 41+ and Safari 8+。这是the demo你可以想象的各种粘性:)

P.S。乍一看,您可能会注意到jQuery的一些内容,但它只是纯JavaScript,只是添加了一个jQuery扩展。