我试图实现此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);
我几周来一直试图解决这个问题,这让我感到疯狂。任何帮助将不胜感激。
答案 0 :(得分:5)
如果你只是试图达到预期的结果而不一定是自己创造 - 那么,有许多JavaScript库可以提供这些。
例如,Stickyfill实际上是position: sticky
的填充,natively supported only in Firefox 41+ and Safari 8+。这是the demo你可以想象的各种粘性:)
P.S。乍一看,您可能会注意到jQuery的一些内容,但它只是纯JavaScript,只是添加了一个jQuery扩展。