Интересно, что блок, остающийся на одном месте при скроллинге, называют: «перемещающийся», «плавающий», «двигающийся», «подвижный», «скользящий». А фактически он «прилипший», «неподвижный», «фиксорованный» и располагающийся на определённом участке экрана монитора, вне зависимости от степени прокрутки веб-страницы.
Исходный вариант, когда ничего не плавает
Изначальные данные: блок уже спозиционирован. У меня как-то так с большим футером, у вас — иначе.
Как сделать блок (div, aside и т.п), рекламу, меню фиксированными. Только CSS
Реализуется благодаря свойству position в значении fixed. Задать положение элемента на экране можно с помощью свойств top, bottom, left, right. Но, поскольку они ведут отсчёт от краёв окна браузера, а мониторы имеют разное разрешение экрана, то лучше сразу правильно разместить блок, опираясь на свойства margin, transform: translate, text-align.
В моём примере я именно так и сделала.
<style>
aside {
position: fixed;
}
<style>
Собственно говоря, для большинства случаев: плавающие кнопки социальных сетей, панели верхнего горизонтального меню, счётчиков, формы заказа звонка, скрипт не требуется.
Как сделать, чтобы блок div прилипал во время прокрутки страницы. Уже скрипт
То есть элемент со ссылками (или чем там ещё) находится далеко от начала страницы. Скажем, шапка большая или боковая колонка содержит много полезностей, таких как поиск, рубрики и т.п. Когда во время скроллинга верхняя часть экрана касается верхнего края элемента, то он приклеивается и "едет" вниз до конца страницы.
Снова возьмём исходный вариант и его изменим на:
<style>
.sticky {
position: fixed;
top: 0;
z-index: 101;
}
</style>
<script>
function offsetPosition(e) { // отступ от верхнего края экрана до элемента
var offsetTop = 0;
do {offsetTop += e.offsetTop;} while (e = e.offsetParent);
return offsetTop;
}
var aside = document.querySelector('aside'),
OP = offsetPosition(aside);
window.onscroll = function() {
aside.className = (OP < window.pageYOffset ? 'sticky' : ''); // если значение прокрутки больше отступа от верхнего края экрана до элемента, то элементу присваивается класс sticky
}
</script>
Плавающий блок, замирающий над футером. Чистый JavaScript без jQuery
Хочу, чтобы если до конца страницы осталось 800px, то плавающий блок не исчезал бы, не заезжал на подвал сайта, а останавливался.
<style>
.prilip {
position: fixed;
z-index: 101;
}
.stop {
position: relative;
}
</style>
<script>
function offsetPosition(e) {
var offsetTop = 0;
do {offsetTop += e.offsetTop;} while (e = e.offsetParent);
return offsetTop;
}
var aside = document.querySelector('aside'),
OP = offsetPosition(aside);
window.onscroll = function() {
// window.pageYOffset - прокрутка;
// document.documentElement.scrollHeight - высота всего документа;
// aside.offsetHeight - высота элемента
if (window.pageYOffset > document.documentElement.scrollHeight - 800 - aside.offsetHeight) {
aside.className = 'stop';
aside.style.top = (document.documentElement.scrollHeight - 800 - aside.offsetHeight - OP) + 'px';
} else {
aside.style.top = '0';
aside.className = (OP < window.pageYOffset ? 'prilip' : '');
}
}
</script>
Элемент прилипает только во время прохождения скроллом другого элемента
Не хочу никаких подсчётов. Да и футер может измениться (растянуться | сузиться) в зависимость от количества содержания. Желаю, чтобы элемент прилипал при касании его верхней границы окном браузера, а отлипал и останавливался, когда заканчивается поле article. То есть нижняя граница article и aside должна быть на одной линии.
<style>
.prilip {
position: fixed;
z-index: 101;
}
.stop {
position: relative;
}
</style>
<script>
function offsetPosition(e) {
var offsetTop = 0;
do {offsetTop += e.offsetTop;} while (e = e.offsetParent);
return offsetTop;
}
var aside = document.querySelector('aside'),
OP = offsetPosition(aside),
article = document.querySelector('article'),
OPa = offsetPosition(article);
window.onscroll = function() {
if (window.pageYOffset > article.offsetHeight - aside.offsetHeight + OPa) {
aside.className = 'stop';
aside.style.top = (article.offsetHeight - aside.offsetHeight - OP + OPa) + 'px';
} else {
aside.style.top = '0';
aside.className = (OP < window.pageYOffset ? 'prilip' : '');
}
}
</script>
Интересно, что блок, остающийся на одном месте при скроллинге, называют: «перемещающийся», «плавающий», «двигающийся», «подвижный», «скользящий». А фактически он «прилипший», «неподвижный», «фиксорованный» и располагающийся на определённом участке экрана монитора, вне зависимости от степени прокрутки веб-страницы.
Исходный вариант, когда ничего не плавает
Изначальные данные: блок уже спозиционирован. У меня как-то так с большим футером, у вас — иначе.
Как сделать блок (div, aside и т.п), рекламу, меню фиксированными. Только CSS
Реализуется благодаря свойству position в значении fixed. Задать положение элемента на экране можно с помощью свойств top, bottom, left, right. Но, поскольку они ведут отсчёт от краёв окна браузера, а мониторы имеют разное разрешение экрана, то лучше сразу правильно разместить блок, опираясь на свойства margin, transform: translate, text-align.
В моём примере я именно так и сделала.
<style>
aside {
position: fixed;
}
<style>
Собственно говоря, для большинства случаев: плавающие кнопки социальных сетей, панели верхнего горизонтального меню, счётчиков, формы заказа звонка, скрипт не требуется.
Как сделать, чтобы блок div прилипал во время прокрутки страницы. Уже скрипт
То есть элемент со ссылками (или чем там ещё) находится далеко от начала страницы. Скажем, шапка большая или боковая колонка содержит много полезностей, таких как поиск, рубрики и т.п. Когда во время скроллинга верхняя часть экрана касается верхнего края элемента, то он приклеивается и "едет" вниз до конца страницы.
Снова возьмём исходный вариант и его изменим на:
<style>
.sticky {
position: fixed;
top: 0;
z-index: 101;
}
</style>
<script>
var aside = document.querySelector('aside'),
t0 = aside.getBoundingClientRect().top - document.documentElement.getBoundingClientRect().top; // отступ от верхнего края окна браузера до элемента
// window.pageYOffset - прокрутка веб-документа
window.addEventListener('scroll', function(e) {
aside.className = (t0 < window.pageYOffset ? 'sticky' : '');
}, false);
</script>
Плавающий блок, замирающий над футером. Чистый JavaScript без jQuery
Хочу, чтобы если до конца страницы осталось 800px, то плавающий блок не исчезал бы, не заезжал на подвал сайта, а останавливался.
<style>
.prilip {
position: fixed;
z-index: 101;
}
.stop {
position: relative;
}
</style>
<script>
// document.documentElement.scrollHeight - высота веб-документа;
// aside.offsetHeight - высота элемента
var aside = document.querySelector('aside'),
t0 = aside.getBoundingClientRect().top - document.documentElement.getBoundingClientRect().top,
t1 = document.documentElement.scrollHeight - 800 - aside.offsetHeight;
function asideScroll() {
if (window.pageYOffset > t1) {
aside.className = 'stop';
aside.style.top = t1 - t0 + 'px';
} else {
aside.className = (t0 < window.pageYOffset ? 'prilip' : '');
aside.style.top = '0';
}
}
window.addEventListener('scroll', asideScroll, false);
</script>
Элемент прилипает только во время прохождения скроллом другого элемента
Не хочу никаких подсчётов. Да и футер может измениться (растянуться | сузиться) в зависимость от количества содержания. Желаю, чтобы элемент прилипал при касании его верхней границы окном браузера, а отлипал и останавливался, когда заканчивается поле article. То есть нижние границы article и aside должны быть на одной линии.
<style>
.prilip {
position: fixed;
z-index: 101;
}
.stop {
position: relative;
}
</style>
<script>
var aside = document.querySelector('aside'),
HTMLtop = document.documentElement.getBoundingClientRect().top,
t0 = aside.getBoundingClientRect().top - HTMLtop,
t2 = document.querySelector('article').getBoundingClientRect().bottom - HTMLtop - aside.offsetHeight;
function asideScroll() {
if (window.pageYOffset > t2) {
aside.className = 'stop';
aside.style.top = t2 - t0 + 'px';
} else {
aside.className = (t0 < window.pageYOffset ? 'prilip' : '');
aside.style.top = '0';
}
}
window.addEventListener('scroll', asideScroll, false);
</script>
Как сделать, чтоб прилипали два (необязательно) блока в обоих сайдбарах
<style>
.prilip {
position: fixed;
z-index: 101;
}
.stop {
position: relative;
}
</style>
<script>
var aside = document.querySelectorAll('#aside, #aside1'); // здесь селекторы блоков, которые будут фиксироваться. Может быть как один блок, так два и более
aside = Array.prototype.slice.call(aside);
aside.forEach(function(aside) {
var t0 = aside.getBoundingClientRect().top,
w = aside.clientWidth;
asideScroll();
window.addEventListener('scroll', asideScroll, false);
function asideScroll() {
var p = 40, // это отступ в px, появляющийся при скроллинге, от верхнего окна браузера до элемента. Может быть отрицательным числом. Применим, например, при фиксированном сверху меню. Если не нужен, заменить на ноль
po = window.pageYOffset + p,
t2 = document.querySelector('article').getBoundingClientRect().bottom + window.pageYOffset - aside.offsetHeight; // блоки останавливаются при достижении нижнего края article. Можно заменить на id, например, '#main'
if (t0 > po) { // если выше фиксирующихся блоков находятся динамически изменяемые/подгружаемые элементы, в том числе реклама или виджеты соцсетей, то после загрузки веб-документа отступ от верха страницы до блоков может быть изменён, из-за чего блоки съезжают. Если таковых нет, можно убрать абзац. Он пересчитывает отступ от верха страницы до летающего блока при скроллинге
t0 = aside.getBoundingClientRect().top + window.pageYOffset;
}
if (po > (t2 - getComputedStyle(aside, '').marginBottom.replace(/px/gi, ''))) { // getComputedStyle(aside, '').marginBottom — это margin-bottom фиксируемого блока. Если не нужен, можно убрать
aside.className = 'stop';
aside.style.top = t2 - t0 + 'px';
} else {
aside.className = (t0 < po ? 'prilip' : '');
aside.style.width = w + 'px'; // одинаковая ширина блока при прокрутки и нет
aside.style.top = p - getComputedStyle(aside, '').marginTop.replace(/px/gi, '') + 'px'; // getComputedStyle(aside, '').marginTop — это margin-top фиксируемого блока. Если не нужен, можно убрать
}
}
});
</script>
Примечания:
- Комментарии (то, что зелёное) желательно убрать, но и с ними всё будет работать.
- id нужного элемента можно посмотреть в коде страницы.
- Чтобы первый экран загрузился предельно быстро, код лучше добавить перед закрывающимся тегом </body>. Практика применима для большинства скриптов. Но его можно добавить и в виджет "Текст" для WordPress, и в гаджет "HTML/JavaScript" для Blogger, и в элемент, который должен перемещаться вместе с прокруткой. Это удобно, когда плавающий блок показан не на всех страницах сайта.
- Благодаря оставленным комментариям код дорабатывался несколько раз. Ряд замечаний были очень полезны! Это здорово! Спасибо вам за участие!
Интересно, что блок, остающийся на одном месте при скроллинге, называют: «перемещающийся», «плавающий», «двигающийся», «подвижный», «скользящий». А фактически он «прилипший», «неподвижный», «фиксорованный» и располагающийся на определённом участке экрана монитора, вне зависимости от степени прокрутки веб-страницы.
Исходный вариант, когда ничего не плавает
Изначальные данные: блок уже спозиционирован. У меня как-то так с большим футером, у вас — иначе.
<header></header> <main> <article id="article"></article> <aside id="aside1"></aside> </main> <footer></footer>
Как сделать блок (div, aside и т.п), рекламу, меню фиксированными. Только CSS
Реализуется благодаря свойству position в значении fixed. Задать положение элемента на экране можно с помощью свойств top, bottom, left, right.
Но, поскольку они ведут отсчёт от краёв окна браузера, а мониторы имеют разное разрешение экрана, то лучше сразу правильно разместить блок, опираясь на свойства margin, transform: translate;, text-align.
<style>
#aside1 { /* селектор блока, который будет оставаться на месте */
position: fixed;
z-index: 101;
}
<style>
Собственно говоря, для большинства случаев: плавающие кнопки социальных сетей, панели верхнего горизонтального меню, счётчиков, формы заказа звонка, скрипт не требуется.
Как сделать, чтобы блок div прилипал во время прокрутки страницы. Уже скрипт
То есть элемент со ссылками (или чем там ещё) находится далеко от начала страницы. Скажем, шапка большая или боковая колонка содержит много полезностей, таких как поиск, рубрики и т.п. Когда во время скроллинга верхняя часть окна браузера касается верхнего края элемента, то он приклеивается и "едет" вниз до конца страницы.
<style>
.sticky {
position: fixed;
top: 0px; /* если ноль заменить на число (и в скрипте тоже), то блок будет прилипать до того, как верхний край окна браузера дойдёт до верхнего края элемента. Может быть отрицательным числом. Применим, например, при фиксированном сверху меню */
z-index: 101;
}
</style>
<script>
(function(){ // анонимная функция (function(){ })(), чтобы переменные R и a не стали глобальными
var R = null,
a = document.querySelector('#aside1'); // селектор блока, который нужно закрепить
window.addEventListener('scroll', Ascroll, false);
document.body.addEventListener('scroll', Ascroll, false); // если у html и body высота равна 100%
function Ascroll() {
if (R == null) { // если блок своим размером, отступами влияет на соседей; если ширина блока не зафиксированна
var Sa = getComputedStyle(a, ''), s = '';
for (var i = 0; i < Sa.length; i++) { // перечисляются стили CSS, которые нужно скопировать с родителя
if (Sa[i].indexOf('box-sizing') == 0 || Sa[i].indexOf('overflow') == 0 || Sa[i].indexOf('width') == 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]) + '; '
}
}
a.innerHTML = '<div style="'+s+'">'+a.innerHTML+'</div>';
a = a.children[0];
R = 0;
}
Ra = a.getBoundingClientRect(), // elem.getBoundingClientRect() возвращает в px координаты элемента относительно верхнего левого угла области просмотра окна браузера
Rb = a.parentNode.getBoundingClientRect();
if (Rb.top <= R) {
a.className = 'sticky';
} else {
a.className = '';
R = Rb.top - Ra.top + 0; // учитываются вышестоящие динамически изменяемые/подгружаемые элементы, в том числе реклама или виджеты соцсетей
}
}
})()
</script>
Плавающий блок, замирающий над футером или другим элементом. Чистый JavaScript без jQuery
Хочу, чтобы плавающий блок не исчезал, не заезжал на подвал сайта, а останавливался над указанным элементом.
<style>
.sticky {
position: fixed;
z-index: 101;
}
.stop {
position: relative;
z-index: 101;
}
</style>
<script>
(function(){
var R = null,
a = document.querySelector('#aside1');
var Sa = getComputedStyle(a, ''), s = '';
for (var i = 0; i < Sa.length; i++) {
if (Sa[i].indexOf('box-sizing') == 0 || Sa[i].indexOf('overflow') == 0 || Sa[i].indexOf('width') == 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]) + '; '
}
}
a.innerHTML = '<div style="'+s+'">'+a.innerHTML+'</div>';
a = a.children[0];
window.addEventListener('scroll', Ascroll, false);
document.body.addEventListener('scroll', Ascroll, false);
function Ascroll() {
var Ra = a.getBoundingClientRect(),
Rb = document.querySelector('footer').getBoundingClientRect(); // селектор блока, при достижении верхнего края которого нужно открепить прилипающий элемент
if (Rb.top <= R) {
if (Rb.top <= Ra.bottom && Ra.top <= 0) {
a.className = 'stop';
a.style.top = R - Ra.height +'px';
} else {
a.className = 'sticky';
a.style.top = '0';
}
} else {
a.className = '';
a.style.top = '';
R = Rb.top - Ra.top + 0;
}
}
})()
</script>
Элемент прилипает только во время прохождения скроллом другого элемента
Хочу, чтобы элемент отцеплялся и останавливался, когда заканчивается поле article. То есть нижние границы article и aside должны быть на одной линии.
<style>
.sticky {
position: fixed;
top: 0;
z-index: 101;
}
.stop {
position: relative;
z-index: 101;
}
</style>
<script>
var a = document.querySelector('#aside1'),
b = document.querySelector('#article'), // селектор блока, при достижении нижнего края которого нужно открепить прилипающий элемент
R = b.getBoundingClientRect().top - a.getBoundingClientRect().top;
window.addEventListener('scroll', Ascroll, false);
document.body.addEventListener('scroll', Ascroll, false);
function Ascroll() {
var Ra = a.getBoundingClientRect(), Rb = b.getBoundingClientRect();
if (Rb.top <= R) {
if (Rb.bottom <= Ra.bottom && Ra.top <= 0) {
a.className = 'stop';
a.style.top = Rb.height - Ra.height + R +'px';
} else {
a.className = 'sticky';
a.style.top = '';
}
} else {
a.className = '';
R = Rb.top - Ra.top;
}
}
</script>
Как сделать, чтоб прилипали два (необязательно) блока в обоих сайдбарах
<style>
.prilip {
position: fixed;
z-index: 101;
}
.stop {
position: relative;
}
</style>
<script>
var aside = document.querySelectorAll('#aside, #aside1'); // здесь селекторы блоков, которые будут фиксироваться. Может быть как один блок, так два и более
aside = Array.prototype.slice.call(aside);
aside.forEach(function(aside) {
var t0 = aside.getBoundingClientRect().top,
w = aside.clientWidth;
asideScroll();
window.addEventListener('scroll', asideScroll, false);
function asideScroll() {
var p = 40, // это отступ в px, появляющийся при скроллинге, от верхнего окна браузера до элемента. Может быть отрицательным числом. Применим, например, при фиксированном сверху меню. Если не нужен, заменить на ноль
po = window.pageYOffset + p,
t2 = document.querySelector('article').getBoundingClientRect().bottom + window.pageYOffset - aside.offsetHeight; // блоки останавливаются при достижении нижнего края article. Можно заменить на id, например, '#main'
if (t0 > po) { // если выше фиксирующихся блоков находятся динамически изменяемые/подгружаемые элементы, в том числе реклама или виджеты соцсетей, то после загрузки веб-документа отступ от верха страницы до блоков может быть изменён, из-за чего блоки съезжают. Если таковых нет, можно убрать абзац. Он пересчитывает отступ от верха страницы до летающего блока при скроллинге
t0 = aside.getBoundingClientRect().top + window.pageYOffset;
}
if (po > (t2 - getComputedStyle(aside, '').marginBottom.replace(/px/gi, ''))) { // getComputedStyle(aside, '').marginBottom — это margin-bottom фиксируемого блока. Если не нужен, можно убрать
aside.className = 'stop';
aside.style.top = t2 - t0 + 'px';
} else {
aside.className = (t0 < po ? 'prilip' : '');
aside.style.width = w + 'px'; // одинаковая ширина блока при прокрутки и нет
aside.style.top = p - getComputedStyle(aside, '').marginTop.replace(/px/gi, '') + 'px'; // getComputedStyle(aside, '').marginTop — это margin-top фиксируемого блока. Если не нужен, можно убрать
}
}
});
</script>
Примечания:
- Комментарии (то, что оформлено зелёным цветом) желательно убрать, но и с ними всё будет работать.
- В коде учтён широки круг условий, поэтому нужные не всем участки (то, что оформлено приглушённым цветом) можно также убрать.
- id нужного элемента можно посмотреть в коде страницы.
- Чтобы первый экран загрузился предельно быстро, код лучше добавить перед закрывающимся тегом </body>. Практика применима для большинства скриптов. Но его можно добавить и в виджет "Текст" для WordPress, и в гаджет "HTML/JavaScript" для Blogger, которые в коде находятся ниже приклеивающегося элемента. Код можно поместить и в сам элемент, который должен перемещаться вместе с прокруткой. Это удобно, когда плавающий блок показан не на всех страницах сайта.
- Для сайтов с адаптивным дизайном действие скрипта ограничить шириной экрана.
- Благодаря оставленным комментариям код дорабатывался несколько раз. Ряд замечаний были очень полезны! Это здорово! Спасибо вам за участие!
Отправить комментарий