JSFiddle - React, Tailwind, and code Playground
by Ayri Rin
HTML
<header>
<a href="http://shpargalkablog.ru/2013/09/scroll-block.html">sticky javascript</a>
</header>
<div style="clear:both;"></div><main>
<article id="article"><h1>Блок приклеивается во время прокрутки страницы. Но перед футером останавливается.</h1></article>
<aside id="aside1">1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20</aside>
</main>
<footer></footer>
CSS
.sticky {
position: fixed;
z-index: 101;
}
.stop {
position: relative;
z-index: 101;
}
body {
background: #aba;
}
header, main, footer {
display: block;
max-width: 740px;
margin: 0 auto;
}
header {
margin-bottom: 15px;
font-size: 200%;
background: #456;
text-align: center;
}
header a {
color: #fff;
}
article {
display: block;
float: left;
width: 485px;
height: 1000px;
background: #fff;
}
aside {
display: block;
margin-left: 500px;
box-shadow: 0 0 0 1px #cff inset;
background: #cdc;
}
footer {
position: relative;
top: 15px;
margin-bottom: 15px;
clear: both;
height: 800px;
background: #456;
}
JavaScript
(function(){
var a = document.querySelector('#aside1'), b = null, P = 0; // если ноль заменить на число, то блок будет прилипать до того, как верхний край окна браузера дойдёт до верхнего края элемента. Может быть отрицательным числом
window.addEventListener('scroll', Ascroll, false);
document.body.addEventListener('scroll', Ascroll, false);
function Ascroll() {
if (b == null) {
var Sa = getComputedStyle(a, ''), s = '';
for (var i = 0; i < Sa.length; i++) {
if (Sa[i].indexOf('overflow') == 0 || Sa[i].indexOf('padding') == 0 || Sa[i].indexOf('border') == 0 || Sa[i].indexOf('outline') == 0 || Sa[i].indexOf('box-shadow') == 0 || Sa[i].indexOf('background') == 0) {
s += Sa[i] + ': ' +Sa.getPropertyValue(Sa[i]) + '; '
}
}
b = document.createElement('div');
b.style.cssText = s + ' box-sizing: border-box; width: ' + a.offsetWidth + 'px;';
a.insertBefore(b, a.firstChild);
var l = a.childNodes.length;
for (var i = 1; i < l; i++) {
b.appendChild(a.childNodes[1]);
}
a.style.height = b.getBoundingClientRect().height + 'px';
a.style.padding = '0';
a.style.border = '0';
}
var Ra = a.getBoundingClientRect(),
R = Math.round(Ra.top + b.getBoundingClientRect().height - document.querySelector('footer').getBoundingClientRect().top + 0); // селектор блока, при достижении верхнего края которого нужно открепить прилипающий элемент; Math.round() только для IE; если ноль заменить на число, то блок будет прилипать до того, как нижний край элемента дойдёт до футера
if ((Ra.top - P) <= 0) {
if ((Ra.top - P) <= R) {
b.className = 'stop';
b.style.top = - R +'px';
} else {
b.className = 'sticky';
b.style.top = P + 'px';
}
} else {
b.className = '';
b.style.top = '';
}
window.addEventListener('resize', function() {
a.children[0].style.width = getComputedStyle(a, '').width
}, false);
}
})()