- Исходный вариант
- CSS ( position: fixed; )
- JS (прилипает не сразу)
- JS (останавливается перед верхней границей)
- JS (останавливается перед нижней границей)
- JS (останавливаются одновременно)
- JS (останавливаются друг за другом)
- JS (длинная)
- Вот что должно подразумеваться в CSS под "плавающим div" — свойство float
- А под "фиксированным" — элемент, которому заданы высота и ширина не в процентах, а в других единицах
- Плавная прокрутка страницы при клике по ссылке
- Кнопка прокрутки страницы "ВВЕРХ"
- Резиновая верстка сайта с плавающей боковой колонкой
Интересно, что блок, остающийся на одном месте при скроллинге, называют: «перемещающийся», «плавающий», «двигающийся», «подвижный», «скользящий». А фактически он «прилипший», «неподвижный», «фиксорованный» и располагающийся на определённом участке экрана монитора, вне зависимости от степени прокрутки веб-страницы.
Исходный вариант, когда ничего не плавает
Изначальные данные: блок уже спозиционирован. У меня как-то так с большим футером, у вас — иначе.
<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(){ })(), чтобы переменные "a" и "b" не стали глобальными var a = document.querySelector('#aside1'), b = null; // селектор блока, который нужно закрепить window.addEventListener('scroll', Ascroll, false); document.body.addEventListener('scroll', Ascroll, false); // если у html и body высота равна 100% function Ascroll() { if (b == null) { // добавить потомка-обёртку, чтобы убрать зависимость с соседями var Sa = getComputedStyle(a, ''), s = ''; for (var i = 0; i < Sa.length; i++) { // перечислить стили CSS, которые нужно скопировать с родителя 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'; // если элементу присвоен padding или border } if (a.getBoundingClientRect().top <= 0) { // elem.getBoundingClientRect() возвращает в px координаты элемента относительно верхнего левого угла области просмотра окна браузера b.className = 'sticky'; } else { b.className = ''; } window.addEventListener('resize', function() { a.children[0].style.width = getComputedStyle(a, '').width }, false); // если изменить размер окна браузера, измениться ширина элемента } })() </script>
Плавающий блок, замирающий над футером или другим элементом. Чистый JavaScript без jQuery
Чтобы плавающий блок не исчезал, не заезжал на подвал сайта, а останавливался над указанным элементом.
<style> .sticky { position: fixed; z-index: 101; } .stop { position: relative; z-index: 101; } </style> <script> (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); } })() </script>
Элемент прилипает только во время прохождения скроллом другого элемента
Чтобы элемент отцеплялся и останавливался, когда заканчивается поле article
. То есть нижние границы article
и aside
должны быть на одной линии.
<style> .sticky { position: fixed; z-index: 101; } .stop { position: relative; z-index: 101; } </style> <script> (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('#article').getBoundingClientRect().bottom); // селектор блока, при достижении нижнего края которого нужно открепить прилипающий элемент 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); } })() </script>
Как сделать, чтоб прилипали два (необязательно) блока в обоих сайдбарах
<style> .sticky { position: fixed; z-index: 101; } .stop { position: relative; z-index: 101; } </style> <header></header> <main> <aside id="aside1"> <div></div> <div></div> <div></div> </aside> <article id="article"></article> <aside id="aside2"> <div></div> <div></div> </aside> </main> <footer></footer> <script> Array.prototype.slice.call(document.querySelectorAll('#aside1 > div:nth-child(3), #aside2 > div:nth-child(2)')).forEach(function(a) { // селекторы блоков, которые будут фиксироваться. Может быть как один блок, так два и более var 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('#article').getBoundingClientRect().bottom + 0); if ((Ra.top - P) <= 0) { if ((Ra.top - P) <= R) { b.className = 'stop'; b.style.top = - R +'px'; b.style.left = 0; } else { b.className = 'sticky'; b.style.top = P + 'px'; b.style.left = Ra.left + 'px'; } } else { b.className = ''; b.style.top = ''; b.style.left = ''; } window.addEventListener('resize', function() { a.children[0].style.width = getComputedStyle(a, '').width; b.style.left = (b.className == 'sticky' ? (a.getBoundingClientRect().left + 'px') : '0'); }, false); } }) </script>
Фиксируется два и более блока друг за другом
При листании вниз прилипает первый блок, когда родитель заканчивается — отлипает; прилипает второй, когда родитель заканчивается — отлипает; прилипает третий и т.д.
<style> .sticky { position: fixed; z-index: 101; } .stop { position: relative; z-index: 101; } </style> <header></header> <main> <article id="article"></article> <aside id="aside1"> <div> <div class="stickyDa"></div> <div></div> <div></div> </div> <div> <div class="stickyDa"></div> <div></div> </div> <div> <div class="stickyDa"></div> <div></div> <div></div> <div></div> </div> </aside> </main> <footer></footer> <script> Array.prototype.slice.call(document.querySelectorAll('#aside1 div.stickyDa')).forEach(function(a) { var 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 - a.parentNode.getBoundingClientRect().bottom + parseFloat(getComputedStyle(a.parentNode, '').paddingBottom.slice(0, -2))); 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); } }) </script>
То же самое, только с общим родителем.
<style> #aside1 { padding: 5px; } #aside1 div + div { margin-top: 5px; } .sticky { position: fixed; z-index: 101; } .stop { position: relative; z-index: 101; } </style> <header></header> <main> <article id="article"></article> <aside id="aside1"> <div class="stickyDa"></div> <div></div> <div></div> <div class="stickyDa"></div> <div></div> <div class="stickyDa"></div> <div></div> <div></div> <div></div> </aside> </main> <footer></footer> <script> (function(){ var A0 = document.querySelector('#aside1'), A1 = A0.querySelectorAll('.stickyDa'); Array.prototype.slice.call(A1).forEach(function(a, index) { var 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, Rh = Ra.top + b.getBoundingClientRect().height; if (A1[index+1] != undefined) { R = Math.round(Rh - A1[index+1].getBoundingClientRect().top + 5); // расстояние между блоками, чтобы плавающие элементы не прижимались вплотную друг к другу } else { R = Math.round(Rh - A0.getBoundingClientRect().bottom + parseFloat(getComputedStyle(A0, '').paddingBottom.slice(0, -2))); } 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 = 'stop'; b.style.top = '0'; } window.addEventListener('resize', function() { a.children[0].style.width = getComputedStyle(a, '').width }, false); } }) })() </script>
Плавающая длинная боковая колонка без пустого пространства
При скроллинге вниз боковая колонка прилипает, когда её нижний край касается нижнего края окна браузера. При скроллинге вверх боковая колонка прилипает, когда её верхний край касается верхнего края окна браузера. Есть нижний предел, до которого доходит колонка.
<style> .sticky { position: fixed; z-index: 101; } .stop { position: relative; z-index: 101; } </style> <script> (function(){ var a = document.querySelector('#aside1'), b = null, K = null, Z = 0, P = 0, N = 0; // если у P ноль заменить на число, то блок будет прилипать до того, как верхний край окна браузера дойдёт до верхнего края элемента, если у N — нижний край дойдёт до нижнего края элемента. Может быть отрицательным числом window.addEventListener('scroll', Ascroll, false); document.body.addEventListener('scroll', Ascroll, false); function Ascroll() { var Ra = a.getBoundingClientRect(), R1bottom = document.querySelector('#article').getBoundingClientRect().bottom; if (Ra.bottom < R1bottom) { 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.className = "stop"; 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 Rb = b.getBoundingClientRect(), Rh = Ra.top + Rb.height, W = document.documentElement.clientHeight, R1 = Math.round(Rh - R1bottom), R2 = Math.round(Rh - W); if (Rb.height > W) { if (Ra.top < K) { // скролл вниз if (R2 + N > R1) { // не дойти до низа if (Rb.bottom - W + N <= 0) { // подцепиться b.className = 'sticky'; b.style.top = W - Rb.height - N + 'px'; Z = N + Ra.top + Rb.height - W; } else { b.className = 'stop'; b.style.top = - Z + 'px'; } } else { b.className = 'stop'; b.style.top = - R1 +'px'; Z = R1; } } else { // скролл вверх if (Ra.top - P < 0) { // не дойти до верха if (Rb.top - P >= 0) { // подцепиться b.className = 'sticky'; b.style.top = P + 'px'; Z = Ra.top - P; } else { b.className = 'stop'; b.style.top = - Z + 'px'; } } else { b.className = ''; b.style.top = ''; Z = 0; } } K = Ra.top; } else { if ((Ra.top - P) <= 0) { if ((Ra.top - P) <= R1) { b.className = 'stop'; b.style.top = - R1 +'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); } } })() </script>
Примечания:
- Комментарии (то, что оформлено зелёным цветом) желательно убрать, но и с ними всё будет работать.
- В коде учтён широки круг условий, поэтому нужные не всем участки (то, что оформлено приглушённым цветом) можно также убрать.
- id нужного элемента можно посмотреть в коде страницы.
- Чтобы первый экран загрузился предельно быстро, код лучше добавить перед закрывающимся тегом </body>. Практика применима для большинства скриптов. Но его можно добавить и в виджет "Текст" для WordPress, и в гаджет "HTML/JavaScript" для Blogger, которые в коде находятся ниже приклеивающегося элемента. Код можно поместить даже в сам элемент, который должен перемещаться вместе с прокруткой, что удобно, когда плавающий блок показан не на всех страницах сайта.
- Для сайтов с адаптивным дизайном действие скрипта следует ограничить шириной экрана.
- Благодаря оставленным комментариям код дорабатывался несколько раз. Ряд замечаний были очень полезны! Это здорово! Спасибо вам за участие!
264 комментария:
1 – 200 из 264 Новые› Самые новые»Не знаете, с чем это может быть связано?
Здорово. Спасибо большое еще раз. Сейчас потестирую по-всякому.
<script>
код скрипта
</script>
нужно писать как
<script>
//<![CDATA[
код скрипта
//]]>
</script>
Особенность блогоплатформы :))
кроме как на вики ещё не видел такой реализии как у вас, очень понравилось. Если я правильно понял, то там есть некое условие, когда например на странице больше одного заголовка, к похожим постам, добавляется ещё содержание поста, согласно заголовкам. Не подскажите как это реализовать? Андрей
Сейчас с border хочу сделать что-то более менее удобное: http://shpargalkablog.ru/2013/09/border-image.html#borderimage Далеко ещё до конечной реализации. Но идею можно уже сейчас увидеть. Нажмите в "Содержание" border и border-image
document.documentElement.scrollTop
вместо
window.pageYOffset
Заранее благодарю!!!
Скрипт в футер?
<style в коде страницы над баннером?
А в коде баннера что указать и в каких тегах?
Нужно еще что-то указывать,исправлять в коде?
Спасибо
чтобы не палить никому :) kodikupon точка ru, к примеру в статье хофф мебель, много инфы и хот-ся чтобы хомяк настойчиво маячил сбоку при прокрутке
document.querySelector('#text-7')
весь код скопируйте и вставьте сначала прямо в статью на вкладке html. Работает?
Код скрипта вставлять в статью? или в виджет "Текст" где код хомяка?
Если в статью, то есть в шаблон записи WP? чтобы на всех страницах работал. Или как? :)
Но! :)
1. Как узнать, что хомяк именно #text-7? вдруг я его заменю,или на другом сайте также захочу:)
2. А если захот-ся сделать, чтобы и форма подписки на новости (+хомяк) прилипла. как тогда указать?
З.Ы. Да,виджет Текст в WP. поддерживает html и служит для вывода кода или надписей и т.п.
Плюс я очень хорошо разбираюсь в селекторах и псевдоклассах и превосходно могу обходиться и без id.
http://shpargalkablog.ru/2011/08/kak-ispolzovat-css.html
http://shpargalkablog.ru/2011/10/css-selectors.html
http://shpargalkablog.ru/2012/02/psevdoklassy-css.html
И это до кучи http://shpargalkablog.ru/2013/04/value-input-javascript.html
Дело в том что сначала происходит сдвиг странички, отрисовка и уже только потом приходит событие, но блок то уже проскочил.
Из-за чего виден неприятный скачек. :(
Это хорошо заметно если вы header сделаете побольше, скажем 200-300 пикселей.
НЕ работает... не понимаю, почему...
поменяла, но все равно не работает...(
а с этим что делать?
.prilip {
position: fixed;
z-index: 101;
}
.stop {
position: relative;
}
куда это вставлять? )
это мне знакомо. но как сделать прокрутку?
я сайдбар зафиксировала (position: fixed;), но содержимое сайдбара не прокручивается(
Какой адрес сайта?
"При position: fixed; и не будет." а как тогда сделать чтобы блок был зафиксирован и прокручивалось содержимое?
А а html у меня просто блок div ="sidebar", который как раз необходимо сделать плавающим
По скриптам лучше обращаться на форум javascript.ru. Там не только код можно выложить, а также то, что он делает.
http://www.imastera.ru/index/obratnaja_svjaz/0-74
var aside = document.querySelector('table[style="border-collapse:collapse;width:100%;"]'),
OP = offsetPosition(aside),
article = document.querySelector('#centerBlock > table > tbody > tr:nth-child(3) > td'),
OPa = offsetPosition(article);
спасибо
В CSS:
#obrsv {
display: inline-block;
width: 1050px;
height: 89px;
background: #cdc;
}
.sticky {
position: fixed;
top: 0;
z-index: 101;
}
В HTML:
function offsetPosition(e) { // отступ от верхнего края экрана до элемента
var offsetTop = 897;
do {offsetTop += e.offsetTop;} while (e = e.offsetParent);
return offsetTop;
}
var aside = document.querySelector('#obrsv'),
OP = offsetPosition(aside);
window.onscroll = function() {
aside.className = (OP < window.pageYOffset ? 'sticky' : ''); // если значение прокрутки больше отступа от верхнего края экрана до элемента, то элементу присваивается класс sticky
}
"<" /div ">"
<div id="obrsv" align="center"><div>
<span style="font-family: Verdana; font-size: medium;"><img style="margin-right: 0px;" alt="" src="http://www.imastera.ru/pozvinite_nam.png" height="89" width="272">
</span>
<a href="javascript://" onclick="openchat();"><img onmouseover="this.src='/obratnij_zvonok2.png';" onmouseout="this.src='/obratnij_zvonok.png';" alt="image001" src="http://www.imastera.ru/obratnij_zvonok.png" style="margin-left: 0px; height=" 89px"="" width="272px"></a>
<a target="_blank" href="http://www.vk.com/imactepa"><img style="" onmouseover="this.src='/knopka_vstupi_vk_white.png';" onmouseout="this.src='/knopka_vstupi_vk.png';" alt="image001" src="http://www.imastera.ru/knopka_vstupi_vk.png" height="89" width="272"></a></div></div>
Тогда стиль и скрипт:
<style>
.prilip {
position: fixed;
bottom: 0;
left: calc(50% - 1050px/2);
z-index: 101;
}
#obrsv, #obrsv div {
display: inline-block;
width: 1050px;
height: 89px;
background: #cdc;
}
</style>
<script>
function offsetPosition(e) {
var offsetTop = 0;
do {offsetTop += e.offsetTop;} while (e = e.offsetParent);
return offsetTop;
}
var aside = document.querySelector('#obrsv div'),
OP = offsetPosition(aside);
window.onscroll = function() {
aside.className = (OP < window.pageYOffset && window.pageYOffset < document.documentElement.scrollHeight - document.documentElement.clientHeight - 200 ? 'prilip' : '');
}
</script>
p.s. aside без стиля так как просто обвертка для блоков. Хотелось бы чтоб дивы плавали внутри aside
И вместо
var aside = document.querySelector('aside'),
напишите
var aside = document.querySelector('#scroll')
А вместо
article = document.querySelector('article'),
вставьте
article = document.querySelector('article > .content'),
Позитивный у тебя блог. Спасибо!
Вот пытаюсь последний скрипт понять, и никак не получается, совсем не могу понять зачем у aside берется текущая позиция в скрипте. Если его позиционирование зависит только от скрола и позиции article.
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' : '');
}
article = document.querySelector('article'),
Я не имел ввиду что знаю как лучше, просто не мог понять как оно работает, но сейчас вроде понял. Хотел просто разобраться для собственного удовольствия.
Что я делаю не так?
Вот сайт: http://lubus.ru/dev0
см. #sidebar-left - он должен плавать...
$(document).ready(function() { ... });
Благодарю!
поменяйте на
article = document.getElementById('wrapper-content'),
$(document).ready(function() { ... });
Реализую кнопку "вверх" по Вашей статье и у меня возникла сложность такого плана. В моем блоге три колонки, текст статей в средней. Кнопку "вверх" я хочу поместить между средней и правой колонкой. Внешне все получилось, но при наведении мышкой на эту кнопку, выделяется (становится активной) вся правая область (от кнопки вверх и вправо до самых краев экрана), тем самым делая невозможным выбор объектов правой колонки. Я честно пыталась разобраться сама, но не получилось. Вопрос: как сделать так, чтобы при наведении мышкой на кнопку "Вверх" становилась активной только сама эта кнопка, а не целая область, в которой кнопка находится. Буду рада, если подскажите, как решить проблему. Заранее спасибо.
a#vverh {
position: fixed;
margin-left: -7em;
bottom: 1em;
text-decoration: none;
color: #bbb;
transition: 1s;
}
Спасибо за быстрый ответ! Кусочек кода, который Вы предложили здесь, к сожалению не помог, все равно подсвечивалась теперь уже вся колонка с текстом статьи, и мешала пользоваться "Похожими статьями".
Методом научного тыка, наизменявши все и вся, у меня решить получилось, но вышло чудовищно криво. Я даже не знаю, правильные ли я параметры туда вписала, и нужны ли они [в таком составе] вообще! www.o-germanii.com. В идеале текст должен быть под стрелкой, а при наведении мышью подсвечиваться и стрелка и текст, и только они. Вышло, как вышло, но пока работает...
Еще раз хочу поблагодарить Вас за помощь и внимание!
<script>
function offsetPosition(e) {
var offsetTop = 0;
do {offsetTop += e.offsetTop;} while (e = e.offsetParent);
return offsetTop;
}
var aside = document.querySelector('#text-132'),
OP = offsetPosition(aside),
aside1 = document.querySelector('#text-105'),
OP1 = offsetPosition(aside1),
article = document.querySelector('#content'),
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' : '');
}
if (window.pageYOffset > article.offsetHeight - aside1.offsetHeight + OPa) {
aside1.className = 'stop';
aside1.style.top = (article.offsetHeight - aside1.offsetHeight - OP1 + OPa) + 'px';
} else {
aside1.style.top = '0';
aside1.className = (OP1 < window.pageYOffset ? 'prilip' : '');
}
}
</script>
Стили - в файл стилей, скрипт в виджет до кода этой тизерной рекламы. Результата не видно никакого)
Что то, вероятно, я сделал неправильно?
http://recipehealth.ru/akupunktura/akupunktura-protiv-bessonnitsyi.html (прописал код только для статей в этой рубрике)
С уважением, Владимир
будет третий виджет в котором код
Единственное, что увидела http://www.bananapay.ru/show/?block_id=1226&r=http%3A//shpargalkablog.ru/2013/09/scroll-block.html&43976 Что это?
Если на странице вызвать контекстное меню правой кнопкой мыши, то там этот код (который Ваш) виден.
Куда-то я его не туда(
А можно попросить Вас озвучить общие правила вставки этого кода? Может тогда я внедрю его чуть более удачно.
Вот выбрал я вариант "Плавающий блок, замирающий над футером".
Весь приведенный вами код вставил в текстовый виджет (сайт на вордпресс).
То есть всё что между style и /style и всё что между script и /script. - всё вставлено одной кучей в текстовый виджет.
Теперь вопрос: Вот я хочу, например, зафиксировать картинку. Куда ее вставить в этом коде?
До кода, после кода, в середину кода?
Или код style /style нужно вставить в файл css, прописать div
а уже этот div вставлять в виджет? если так то до или после script /script.
Статья хорошая, демо так вообще шикарен. А вот как установить это добро на сайт - непонятно(
совсем этот момент не понятен
2) картинку нужно вставить до скрипта всё равно куда
3) вместо
document.querySelector('aside')
напишите
document.querySelector('ваш_id_картинки_которая_должна_плавать')
Если не разберётесь, то сбросьте адрес страницы, на которой вы делаете изменения с описанием: картинка такая-то, должна доходить до футера и т.п.
document.querySelector('#izo')
NMitra: а почему стили не работают, если размещать их в файле стилей css ?
работают только вместе со скриптом в виджете...
и если поставить aside.style.top = '100px'; (а не ноль) - то блок отскакивает немного вниз "ударившись" о верхний край
1) не вижу причин, почему стили не работают. Вы убираете тег <style>?
2) offsetTop = -100 и aside.style.top = '100px'. Вот тут:
function offsetPosition(e) { // отступ от верхнего края экрана до элемента
var offsetTop = -100;
do {offsetTop += e.offsetTop;} while (e = e.offsetParent);
return offsetTop;
}
Отступ тоже всё ок.
Еще раз спасибо
Анонимный №2, в Blogger вместо
<script>
код скрипта
</script>
в большинстве случаев нужно писать
<script>//<![CDATA[
код скрипта
//]]></script>
#content-wrapper {
position: relative;
}
</style>
<script>
var aside = document.querySelector('#HTML10');
var article = document.querySelector('#content-wrapper');
function offsetPosition(e) {
var offsetTop = 0;
do {offsetTop += e.offsetTop;} while (e = e.offsetParent);
return offsetTop;
}
window.addEventListener('load', function(e) {
var asideTop = offsetPosition(aside);
var articleTop = offsetPosition(article);
this.addEventListener('scroll', function(e) {
if ((document.documentElement.getBoundingClientRect().top * -1) > asideTop) {
if (this.pageYOffset >= article.offsetHeight - aside.offsetHeight + articleTop) {
aside.style.bottom = 0;
aside.style.top = 'auto';
aside.style.position = 'absolute';
} else {
aside.style.bottom = 'auto';
aside.style.top = '0';
aside.style.position = 'fixed';
}
} else {
aside.style.position = '';
}
}, false);
}, false);
</script>
Заранее спасибо!
<style>
.prilip {
position: fixed;
z-index: 101;
}
.stop {
position: relative;
}
</style>
<script>//<![CDATA[
function offsetPosition(e) {
var offsetTop = 0;
do {offsetTop += e.offsetTop;} while (e = e.offsetParent);
return offsetTop;
}
var aside = document.querySelector('#HTML1'),
OP = offsetPosition(aside),
article = document.querySelector('#Blog1'),
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>
Нужно закрепить в правой части полностью все содержимое блока zt-right-inner
Но Вам все равно спасибо, очень многое для себя узнал
Попробовала вставить условие в код в скрипт:
function offsetPosition(e) { // отступ от верхнего края экрана до элемента
var offsetTop = 0;
do {offsetTop += e.offsetTop;} while (e = e.offsetParent);
return offsetTop;
}
var oWidth = document.documentElement.clientWidth; // проверяем разрешение экрана пользователя
var aside = document.querySelector('#tcvn-header'),
OP = offsetPosition( aside);
if(oWidth>='980'){
window.onscroll = function() {
aside.className = (OP < window.pageYOffset ? 'sticky' : ''); // если значение прокрутки больше отступа от верхнего края экрана до элемента, то элементу присваивается класс sticky
}
}
не работает.
var width = window.innerWidth || document.documentElement.clientWidth;
if (width > 540) { }
Может я не туда ставлю условие? Пробовала по-разному - меню или фиксируется, или не фиксируется, на размеры экрана не реагирует .
var width = window.innerWidth || document.documentElement.clientWidth;
if (width > 980) {
function offsetPosition(e) { // отступ от верхнего края экрана до элемента
var offsetTop = 0;
do {offsetTop += e.offsetTop;} while (e = e.offsetParent);
return offsetTop;
}
var aside = document.querySelector('#tcvn-header'),
OP = offsetPosition( aside);
window.onscroll = function() {
aside.className = (OP < window.pageYOffset ? 'sticky' : ''); // если значение прокрутки больше отступа от верхнего края экрана до элемента, то элементу присваивается класс sticky
}
}
@media (min-width: 980px) {
.sticky {
position: fixed;
top: 0;
z-index: 101;
}
}
window.onscroll = function() {
var width = window.innerWidth || document.documentElement.clientWidth;
if (width > 980) {
aside.className = (OP < window.pageYOffset ? 'sticky' : ''); // если значение прокрутки больше отступа от верхнего края экрана до элемента, то элементу присваивается класс sticky
}
}
как-то совсем не в ту сторону думала
прописала в лоб в css
@media (min-width: 980px) {
#tcvn-header {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 101;
-webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.15);
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.15);} }
Спасибо большое за помощь! теперь работает !
скрипт
function offsetPosition(e) { // отступ от верхнего края экрана до элемента
var offsetTop = 0;
do {offsetTop += e.offsetTop;} while (e = e.offsetParent);
return offsetTop;
}
var aside = document.querySelector('#tcvn-header'),
OP = offsetPosition( aside);
window.onscroll = function() {
aside.className = (OP < window.pageYOffset ? 'sticky' : ''); // если значение прокрутки больше отступа от верхнего края экрана до элемента, то элементу присваивается класс sticky
}
в css :
@media (min-width: 980px) {
.sticky {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 101;
-webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.15);
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.15);}
}
Реализовал Ваш пример (header как не трудно догадаться): tekstilroom.ru . Однако в разных браузерах из-за разного шага прокрутки, "эффект прилипания" смотрится от сносного до некачественного. Transition: top не действует, к сожалению, а других более глубоких познаний пока нет)). Подскажите, пожалуйста, как бы смягчить "эффект прилипания"? Заранее Вам благодарен, Степан.
<script>
var nav = document.querySelector('.tm-top-block.tm-grid-block nav');
nav.parentNode.style.height = nav.clientHeight+'px';
window.addEventListener('scroll', function(e) {
nav.className = (document.querySelector('.tm-headerbar.uk-clearfix.uk-hidden-small').clientHeight < this.pageYOffset ? 'sticky' : 'uk-navbar');
}, false);
</script>
и куда вставлять тот код, что с торможением перед окончанием странички? Если вместо исходного(как его найти тогда) или в любом месте? Посоветуйте чайнику, плиз.
Вы можете подсказать, что добавить в этот код, чтобы футер появлялся не сразу, а как сделано на: http://www.concretenetwork.com/concrete_overlays_cement/
Мой сайт: allfacades.com, но на нем еще не установлен ваш код.
Спасибо заранее!
Извините!
Есть форум ( http://bioforum.bioresurse.ru ), в правой колонке модуль с рекламой, хочу его закрепитю.
Пытался в сам модуль ставить скрипт - не работает
var aside = document.querySelector('#myobj'),
t0 = aside.getBoundingClientRect().top,
t2 = document.querySelector('article.art-post').getBoundingClientRect().bottom - aside.offsetHeight;
window.addEventListener('scroll', function(e) {
if (window.pageYOffset > t2) {
aside.className = 'stop';
aside.style.top = t2 - t0 + 'px';
} else {
aside.className = (t0 < window.pageYOffset ? 'prilip' : '');
aside.style.top = '0';
}
}, false);
К сожалению, не могу разобраться с "плавающем" блоком, как его установить на блогспот.
Создаю виджет "html/javascript", туда вставляю код из последнего примера, узнаю номер этого виджета, в моем случае это HTML23.
Вопрос, что делать дальше, заменить везде в коде aside на #HTML23?
И на что заменить у меня article, на fauxcolumn-outer fauxcolumn-center-outer?
Пробую и так и так, но что то не получается ничего, если будет возможность, посмотрите как это можно сделать.
сайт italian-blog.com
var aside = document.querySelector('#HTML23'),
t0 = aside.getBoundingClientRect().top,
t2 = document.querySelector('.fauxcolumn-outer.fauxcolumn-right-outer').getBoundingClientRect().bottom - aside.offsetHeight;
window.addEventListener('scroll', function(e) {
if (window.pageYOffset > t2) {
aside.className = 'stop';
aside.style.top = t2 - t0 + 'px';
} else {
aside.className = (t0 < window.pageYOffset ? 'prilip' : '');
aside.style.top = '0';
}
}, false);
Но заработал немного странно :)
начинает показываться еще до того, как до него прокрутили страницу,
т.е. накладывается на блоки, которые выше него в боковой колонке.
Уже с виджета вконтакте появляется надпись "тест тест1",
и затем какое то время блок остается "прилипшим" к верхней границе,
но при продолжении прокрутки страницы далеко вниз - исчезает.
вот, пример, длинной страницы, где это видно
http://www.italian-blog.com/2013/10/poluchenie-italianskoi-vizy.html
Если эти правки трудоемкие, то напишите на почту,
чтобы можно было договориться с вами о решении этой задачи за вознаграждение.
n.mitra@yandex.ru
У меня к Вам вопрос следующего рода!!!
использую последний код....
У меня проблема в следующем....Там можно использовать два и более плавающих блока....Так вот..Располагаются они у меня в правой части один, под другим...С выборкой селекторов, вопросов не возникло...Вот только , если использую больше одного блока (в данном случае 2), то при прокрутке, они наезжают друг на друга...
Где это можно поправить???
Заранее спасибо!!!
Или их нужно взять в одну обёртку div (если между ними нет других не нужных элементов), или рассчитывать для нижнего блока отступ с учётом высоты верхнего (.offsetHeight), то есть
aside.forEach(function(aside) {
заменить на
aside.forEach(function(aside, asideN, asideArr) {
var p = 40,
заменить на
var p = (asideN == 1 ? (40+parseFloat(asideArr[0].offsetHeight)) : 40);
"Элемент прилипает только во время прохождения скроллом другого элемента"
Содержимое вставляю в блок HTML/JavaScript
Код: (интересует блок с телефонами)
http://pastebin.com/znPcYdrQ
Вот только оно почему то не работает, даже признаков нет
_http://nechipuruk.blogspot.com/
Код вставил в блок TEST.PRILIP
Можно так сделать ...?
t0 = document.querySelector('.column-left-inner').getBoundingClientRect().top - HTMLtop,
var aside = document.querySelector('#Text1'),
HTMLtop = document.documentElement.getBoundingClientRect().top,
t0 = document.querySelector('.column-left-inner').getBoundingClientRect().bottom - HTMLtop + aside.offsetHeight,
t2 = document.querySelector('.date-posts').getBoundingClientRect().bottom - HTMLtop - aside.offsetHeight;
Отлично, работает как часы.
Спасибо Наталья, за помощь и ваш труд
Будьте добры, подскажите пожалуйста, а то что-то совсем запуталась.
Плавающий блок, замирающий над футером. Блок должен быть всегда внизу окна, шириной 100%, высотой 40px, но дальше футера(110px) не уползать.
Заранее спасибо, и отдельная благодарность Вам за Ваши труды! Отличный блог!
Diana Yurieva, есть вариант (см. комментарий 133), но не знаю этично ли будет публиковать.
У меня проблема по созданию плавающего блока такая.
Плавающий блок длинный и не входит в один экран, поэтому хотелось, чтобы при прокрутке вниз блок прокручивался до своей нижней точки, а потом прилипал и двигался до футера.
При прокрутке вверх, плавающий блок снова прокручивался до своей верхней точки и снова прилипает, чтобы посетитель мог видеть всю высоту блока.....
Такая реализация есть, но когда блок достигает своей нижней точки он "отпрыгивает" вправо, даже не знаю это хорошо или плохо, с одной стороны хорошо - привлекает внимание, а с другой стороны, как деффект..., но хочется такой же и без "прыгания" ...
http://львов-карпаты.com.ua/ru/туры-во-львов/праздники-львов/майские-праздники.html
Какой из Ваших вариантов можно использовать для такой реализации?
С уважением.
Можно ли в варианте 7 "Фиксируется два и более блока друг за другом" - сделать так, чтобы последний блок фиксировался вплоть до самого футера (точнее до отметки "1000пикселей до футера"), а не строго в рамках высоты родителя?
Готов заплатить за подобную реализацию...
И варианте 4 - "Плавающий блок, замирающий над футером или другим элементом. Чистый JavaScript без jQuery" можно ли как нибудь сделать так что бы блок останавливался за, скажем, 1000пикселей до футера?
1) если правильно поняла
a.parentNode.getBoundingClientRect().bottom
заменить на
document.querySelector('#footer').getBoundingClientRect().bottom
2) дополнила, замените ноль на число
Модифицированный 7-ой вариант тоже работает, но криво - фикс-блоки при скроле не отлипают, а накладываются друг на друга по мере прокрутки вниз. Тоесть, допустим, первый блок плывет 200пикселей (высота родителя, установленная мной), далее он должен отлепиться, но этого не происходит, он просто перекрывается вторым блоком и они плывут, наложенные друг на друга, еще 200 пикселей, далее к ним таким же образом добавляется третий блок.... в общем имеем в конце один трехслойный блок)
Вроде вы меня правильно поняли)) Я имел ввиду здесь тоже самое, что и в оригинале скрипта, за исключением того, что последний блок будет плыть уже до конца...до футера.
Последий блок в этой реализации можно отлепливать на определенном расстоянии от футера? (как в 4ом модифицированном варианте).
Array.prototype.slice.call(document.querySelectorAll('#aside1 div.stickyDa')).forEach(function(a) {
заменить на
Array.prototype.slice.call(document.querySelectorAll('#aside1 div.stickyDa')).forEach(function(a, index, all) {
R = Math.round(Ra.top + b.getBoundingClientRect().height - a.parentNode.getBoundingClientRect().bottom + parseFloat(getComputedStyle(a.parentNode, '').paddingBottom.slice(0, -2)));
заменить на
R = (index + 1 == all.length ? Math.round(Ra.top + b.getBoundingClientRect().height - document.querySelector('footer').getBoundingClientRect().top + 0) : Math.round(Ra.top + b.getBoundingClientRect().height - a.parentNode.getBoundingClientRect().bottom + parseFloat(getComputedStyle(a.parentNode, '').paddingBottom.slice(0, -2))));
Вместо нуля ваше значение
Вот мой код если что (это 7-ой вариант, высота первых двух родителей 2500px, последний блок плывет аж до футера, кроме того, задано условие не фиксировать блоки если ширина экрана меньше чем 890px).
Чтоб не копировать сюда столько кода, просто дам ссылку http://gms.pp.ua/code.txt
"насчет уязвимостей, здесь все нормально?" - увы, не так часто посещаю хакер.ру. Могу только сказать, что с точки зрения стандартов всё верно. С поддержкой в старых IE могут быть проблемы, так как последние не поддерживают addEventListener и document.querySelector
window.addEventListener('scroll', function() {
document.querySelector('header').style.left = '-' + document.documentElement.scrollLeft + 'px';
}, false);
Разрешите ещё. В продолжение.
Разметка такая. Если я правильно понимаю.
ширина headera,wrappera,wrapa - 1000px;
header {
position:fixed;
}
header на самом верху - там навигация.
document.querySelector('header').style.left = '-' + document.documentElement.scrollLeft + 'px';
}, false); подключается в head между тегами script? или как?
document.querySelector('header') - это тег <header> Если у вас id, то document.querySelector('#header')
Анонимный, также спасибо за замечание, доработаю.
http://youtu.be/8udLUcNUkAA
Более вдумчиво смогу посмотреть только на следующей неделе.
http://bestool.com.ua/nabori-inctrumentov/univercal-nie-nabori/
Но есть ньюансы:
1. При прокрутке вниз блок скачет (оно какбы терпимо но меня беспокоит) Как можно решить проблему если у меня стоит авто дополнение товаров при прокрутке вниз...
2. Есть проблема по серьезней, при любом скролле страницы пропадает выбор диаппазона цен товаров - значения пропадают а ползунок не передвигается.
Буду очень благодарен, кстати у меня адаптивный сайт и скрипт на нем работает нормально (помимо указаного)
Артем Панчук - artem_panchuk@ukr.net
1. нужно пробовать, ничего путного в голову не приходит (таймер? увеличить высоту боковой колонки на высоту футера?)
2. поправила, пока не переделала для всех вариантов
3. потихоньку исправляюсь :)
window.addEventListener('scroll', function() {
document.querySelector('header').style.left = document.documentElement.getBoundingClientRect().left + 'px';
}, false);
Подскажите пожалуйста, как сделать так, что бы останавливался блок за 200px до конца блока?
Спасибо!
P = 250;
4-ый вариант, мне необходимо, что бы фиксированный блок не доходил до конца другого блока, а заканчивался за 200px до конца.
Как это правильно реализовать!
Большое спасибо!
Там почти тоже самое, что и в 4-ом: разница лишь в том, что 4-ый замирает над верхним краем элемента, а 5-ый - над нижним
Я что-то не то делаю?
Спасибо!
Спасибо!
R = Math.round(Ra.top + b.getBoundingClientRect().height - document.querySelector('#article').getBoundingClientRect().bottom + 250);