Как сделать блок с меню


Как сделать блок с меню

Как сделать блок с меню

Как сделать блок с меню



Интересно, что блок, остающийся на одном месте при скроллинге, называют: «перемещающийся», «плавающий», «двигающийся», «подвижный», «скользящий». А фактически он «прилипший», «неподвижный», «фиксорованный» и располагающийся на определённом участке экрана монитора, вне зависимости от степени прокрутки веб-страницы.

Исходный вариант, когда ничего не плавает

Изначальные данные: блок уже спозиционирован. У меня как-то так с большим футером, у вас — иначе.

<header></header> <main> <article id="article"></article> <aside id="aside1"></aside> </main> <footer></footer>

Как сделать блок (div, aside и т.п), шапку, рекламу, меню фиксированными. Только CSS

Реализуется благодаря . Задать положение элемента на экране можно с помощью свойств top, bottom, left, right.

блок div

Но, поскольку они ведут отсчёт от краёв окна браузера, а мониторы имеют разное разрешение экрана, то лучше сразу правильно разместить блок, опираясь на свойства , , .

<style> #aside1 { position: fixed; z-index: 101; } <style>

Собственно говоря, для большинства случаев: плавающие кнопки социальных сетей, счётчиков, , скрипт не требуется.

Как сделать, чтобы блок div прилипал во время прокрутки страницы. Уже скрипт

То есть элемент со ссылками (или чем там ещё) находится далеко от начала страницы. Скажем, шапка большая или боковая колонка содержит много полезностей, таких как поиск, рубрики и т.п. Когда во время скроллинга верхняя часть окна браузера касается верхнего края элемента, то он приклеивается и "едет" вниз до конца страницы.

<style> .sticky { position: fixed; top: 0px; z-index: 101; } </style> <script> (function(){ var a = document.querySelector('#aside1'), b = null; 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'; } if (a.getBoundingClientRect().top <= 0) { 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); 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; 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>

Примечания:

  1. желательно убрать, но и с ними всё будет работать.
  2. В коде учтён широки круг условий, поэтому нужные не всем участки (то, что оформлено приглушённым цветом) можно также убрать.
  3. .
  4. Чтобы первый экран загрузился предельно быстро, код лучше добавить перед закрывающимся тегом </body>. Практика применима для большинства скриптов. Но его можно добавить и в виджет "Текст" для WordPress, и в гаджет "HTML/JavaScript" для Blogger, которые в коде находятся ниже приклеивающегося элемента. Код можно поместить даже в сам элемент, который должен перемещаться вместе с прокруткой, что удобно, когда плавающий блок показан не на всех страницах сайта.
  5. Для сайтов с адаптивным дизайном действие скрипта следует ограничить шириной экрана.
  6. Благодаря оставленным комментариям код дорабатывался несколько раз. Ряд замечаний были очень полезны! Это здорово! Спасибо вам за участие!

Источник: http://shpargalkablog.ru/2013/09/scroll-block.html


Как сделать блок с меню

Как сделать блок с меню

Как сделать блок с меню

Как сделать блок с меню

Как сделать блок с меню

Как сделать блок с меню

Как сделать блок с меню

Как сделать блок с меню