Javascript 不带jQuery的自由滚动粘性边栏

Javascript 不带jQuery的自由滚动粘性边栏,javascript,sidebar,Javascript,Sidebar,我试图在不依赖jQuery的情况下实现此堆栈溢出问题中概述的内容: 但我不想劫持这个问题 基本上,我希望侧边栏中的内容可以独立滚动,但当视口到达滚动侧边栏内容的任意一端时,内容是固定的 当侧边栏处于绝对位置且位于我已设置为全高的容器顶部和底部之间时,我的主要绊脚石似乎无法计算elementTop变量 完整代码如下: var StickySidebar = function(eventie) { var container, containerTop, containerHeight, //

我试图在不依赖jQuery的情况下实现此堆栈溢出问题中概述的内容:

但我不想劫持这个问题

基本上,我希望侧边栏中的内容可以独立滚动,但当视口到达滚动侧边栏内容的任意一端时,内容是固定的

当侧边栏处于绝对位置且位于我已设置为全高的容器顶部和底部之间时,我的主要绊脚石似乎无法计算
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);
var StickySidebar=函数(事件){
var container,containerTop,containerHeight,//container
元素,元素顶部,元素高度,elStyle,//元素
viewportTop=-1,viewportHeight,documentTop,//视口
lastViewportTop,向下滚动,top=false,bottom=false,//粘滞变量
scroll=window.requestAnimationFrame||
window.webkitRequestAnimationFrame||
window.mozRequestAnimationFrame||
window.msRequestAnimationFrame||
window.oRequestAnimationFrame||
函数(回调){window.setTimeout(回调,1000/60);},
选项={
容器:document.querySelector('.sidebar container'),
元素:document.querySelector('.sidebar'),
侧边栏类:“侧边栏”,
底部偏移:-15,
地形偏移:90,
},
_updateValue=函数(){
视口高度=window.innerHeight;
},
_偏移量=函数(obj){
var ol=ot=0;
if(对象抵销父对象){
做{
ol+=obj.offsetLeft;
ot+=对象偏移量;
}而(对象=对象抵销母公司);
}
返回{
左:ol,,
顶部:ot
};
},
init=函数(){
if(options.element!==null){
container=options.container;
containerTop=偏移量(容器)。顶部;
ContainerHight=container.clientHight;
element=options.element;
elementTop=偏移量(element).top;
elementHeight=options.element.clientHeight;
lastViewportTop=window.scrollY;
视口高度=window.innerHeight;
绑定(文档,“滚动”,_循环);
绑定(窗口,“调整大小”,“更新值”);
}
},
_循环=函数(){
if(viewportTop==window.pageYOffset){
滚动(_循环);
返回false;
}else viewportTop=window.pageYOffset;
_updateValue();
var视口底部、elementTooBig、topOffset;
elementTop=偏移量(element).top;
element高度=element.clientHeight;
ContainerHight=container.clientHight;
向下滚动=viewportTop>lastViewportTop;
elementTooBig=elementHeight>viewportHeight;
控制台日志(“elementTop:+elementTop”);
log(“viewportTop:+viewportTop”);
如果(向下滚动){
如果(视口顶部+视口高度>=元素顶部+元素高度){
setAttribute('style','position:fixed;bottom:30px;');
}否则{
element.setAttribute('style','position:absolute;top:'+elementTop+'px;');//第1期
}
如果(视口顶部+视口高度>容器顶部+容器高度){
setAttribute('style','position:absolute;bottom:0;');
}
}否则{
如果(视口顶部<容器顶部-60){
元素。removeAttribute(“样式”);
返回;
}

if(viewportTop如果您只是尝试实现所需的结果,不一定是自己创建的,那么有很多JavaScript库提供了这一点

例如,实际上是一个polyfill,用于
位置:sticky
,也就是说,这里有各种各样的粘性,你可以想象:)


另外,乍一看,你可能会注意到关于jQuery的一些东西,但它是纯JavaScript的,只是添加了一个jQuery扩展。

你可以用css和
position:fixed;
来解决这个问题。你也可以用在小屏幕上。所以不需要JS。谢谢你的回复,但这不起作用。我不想粗鲁,但我不认为你你完全理解这个问题。你要纯JS吗?我已经试过了,但他使用css转换,而不是打开和关闭固定位置。它起作用了,但性能不理想。这个多边形填充看起来不支持粘到底。@approxib值否,它实际上允许你将元素粘到底部M哪个例子?它说它不能在。@approxiblue Hm,这很奇怪,我刚刚克隆了repo并检查了
demos/demo.html
BTW更新了问题。相同的repo?该文件不存在。