Простий плаваючий блок на jQuery
Останнім часом на сайтах і в блогах стало популярним розміщувати фіксований або правильніше сказати, плаваючий блок, в який можна помістити меню, форму підписки або іншу інформацію. яка повинна бути обов'язково на увазі. Суть в тому, що такий блок спочатку розташований як звичайний елемент, але при прокручуванні фіксується і рухається разом з усією сторінкою. залишаючись видимим.В общем-то мене ця тема не обійшла стороною, і вирішив я зробити собі плаваючі меню, за допомогою jQuery і цього самого фіксованого блоку. І ось менюшка "плаває", як і було задумано, і тепер настав час поділиться тим, як просто і швидко зробити такий плаваючий блок зі зміщенням у себе на сайті або в блозі.
В принципі, простий фіксований блок можливо реалізувати і тільки за допомогою CSS - властивості position зі значенням fixed. але тоді він спочатку буде намертво визначено в заданій точці на моніторі відвідувача і "плаваючим", його буде назвати проблематично. Нам же потрібен блок, який зміщується і фіксується лише при прокручуванні сторінки.
Щоб було зрозуміліше дивимося:
DEMO
Відразу зауважу, що варіантів реалізації в мережі достатньо, але дійсно тямущих не багато. Більшість мають громіздким, часто не потрібним, кодом, а деякі не зовсім і універсальні. Даний варіант найпростіший, без анімацій та іншого - трохи CSS і зовсім небагато jQuery.
HTML буде виглядає так:
Тепер CSS. Відразу додамо і новий клас, у якого позиціонування задамо як fixed:
floating background: # 1c1c1c;
color: #fff;
font: normal normal 14px Tahoma;
padding: 10px;
width: 300px; / * Вказуємо ширину * /
>
.fixed position: fixed;
top: 10px; / * Тут вказуємо відступ зверху * /
z-index: 9999; / * Встановлюємо блок поверх всіх елементів на сторінці * /
>
Позиціонування у блоку .floating. вказувати не потрібно, однак він повинен розташовуватися всередині батьківського елементу, щодо якого буде позиціонуватися на сторінці. Також потрібно вказати ширину інакше при фіксованому позиціюванні він займе всю доступну область і вийде за межі батька.
А ось і сам скрипт jQuery. Його задача проста - коли сторінка прокручена до певної висоти додати клас і зафіксувати блок.
$ (Function () $ (window) .scroll (function () <
var top = $ (document) .scrollTop ();
if (top> 200) $ ( '. floating'). addClass ( 'fixed'); // 200 - це значення висоти прокрутки сторінки для додавання клас
else $ ( '. floating'). removeClass ( 'fixed');
>);
>);
Все що потрібно з оформлення, положенню - прописується в CSS, скрипт виконує, як і належить, організаційну функцію. Простіше не куди.
Не забуваємо що для роботи такого роду лабуди до сайту повинна бути підключена бібліотека jQuery.
$ (Function () var topPos = $ ( '. Floating'). Offset (). Top; // topPos - це значення від верху блоку до вікна браузера
$ (Window) .scroll (function () <
var top = $ (document) .scrollTop ();
if (top> topPos) $ ( '. floating'). addClass ( 'fixed');
else $ ( '. floating'). removeClass ( 'fixed');
>);
>);
Демонстраційна сторінка на початку статті показаний перший варіант скрипта, без доробок.
Як прибрати зміщення контенту, коли блок стає плаваючим
Спочатку, поки блок не став плаваючим, він має відносне позиціонування і повністю бере участь у структурі веб-сторінки, тобто своїми розмірами, зокрема висотою, впливає на стан інших блоків сайту. Коли ж в процесі прокрутки блок набуває, за допомогою скрипта, фіксоване позиціонування, то він випадає із загальної структури та контент або блоки, які перебували нижче, одразу займають звільнені місце. Такий "скачок", природно, не зовсім приємний для розробника і зовсім не приємний для відвідувача. Вирішується ця проблема дуже просто, на рівні HTML і CSS.
Рішення :
Необхідно код плаваючого блоку обернути в додатковий контейнер:
При цьому, висота блоку-обгортки в CSS повинна бути зазначена рівною висоті плаваючого блоку включаючи верхні і нижні, зовнішні і внутрішні відступи:
floating background: # 1c1c1c;
color: #fff;
font: normal normal 14px Tahoma;
padding: 10px;
margin: 5px;
height: 500px;
width: 300px;
>
.container height: 530px; / * Висота блоку + відступи * /
>
В результаті, поки блок буде спокійно прокручуватися разом зі сторінкою, місце для нього буде зарезервувати батьківським контейнером, який не дасть стрибати всього іншого вмісту.
Положення всередині блоків і на сайтах з фіксованою шириною
Так як в реалізації даного варіанту плаваючого блоку використовується додатковий клас з фіксованим позиціонуванням. особливості якого полягають в тому, що положення блоку на веб-сторінці прив'язується ні до батьківським елементів, а до вікна браузера, то природно що на сайтах з точно певною шириною, блок може вести себе некоректно, з'їжджаючи за межі шаблону і батьківських блоків. Однак, і ця проблема вирішується на рівні CSS.
Рішення :
У батьківського блоку повинна бути вказана ширина, будь-яке значення (%, px і т.д.), крім auto.
Для основного класу пл-го блоку, в даному випадки .floating. необхідно точно вказати ширину в абсолютних одиницях (напр. px), при цьому вона, включаючи відступи, не повинна перевищувати ширини блоку батька.
Для додаткового класу, в даному випадки .fixed. в стилях не варто вказувати зміщення вліво і вправо (left і right).
/ * ----- * /
Демо з застосованими рішеннями:
DEMO 1
Маніпуляції з плаваючим блоком щодо інших блоків сайту
Часто виникає проблема, полягає в тому, що якщо блок містить велику кількість інформації, тобто його висота збільшується, то при прокручуванні до низу сторінки, блок, досягаючи підвалу, напливає і наїжджає на нього, перекриваючи і приховуючи його частина.
В ідеалі, при досягненні футера або будь-якого іншого, зазначеного, елемента сторінки, блок повинен зупинятися (припиняти рух) до нього або плавно змінювати видимість, наприклад зникати. Щоб вирішити дану проблему необхідно трохи доповнити скрипт, додавши певні умови поведінки плаваючого блоку в такій ситуації, зберігаючи як і раніше його простоту :)
Рішення :
Внесемо в скрипт змінну, яка буде визначати відстань до необхідного стоп-блоку (наприклад: всі того ж "підвалу"), а також, в іншу зміну отримаємо висоту самого плаваючого блоку і потім додамо, до вже наявних, додаткові умови. В даному випадки зробимо щоб блок зникав при досягненні підвалу. В результаті код скрипта буде виглядати так:
$ (Function () var topPos = $ ( '. Floating'). Offset (). Top;
$ (Window) .scroll (function () <
var top = $ (document) .scrollTop (),
pip = $ ( 'footer'). offset (). top, // відстань до підвалу від верху вікна браузера
height = $ ( '. floating'). outerHeight (); // отримуємо значення висоти пл.блока
if (top> topPos top
else
>);
>);
Мінлива значення висоти - не обов'язкова, якщо висота відома і мінятися не буде можна вказати просто цифрами:
Однак, не завжди потрібно щоб елемент зникав і з'являвся, іноді необхідно щоб плаваючий блок зупинявся при досягненні "підвалу". І в цьому випадки все реалізується досить просто. Код тоді буде таким:
Оскільки в цьому випадки використовується абсолютне позиціонування, то у батьківського елементу, до низу якого буде притискатися пл.блок, в стилях має бути явно вказано відносне позиціонування - position: relative;
Більш детально це видно в прикріплених нижче HTML файлах
Файли з вихідним кодом обох варіантів
Терпіти не можу, коли плаваючі блоки закривають частину тексту поста. Запропонований вами варіант - зовсім інше.
Пішов-ка я на свій блог думати яку ж інформацію в такий плаваючий блок помістити можна. Як тільки придумаю, спробую встановити.
Дякую за корисну інфу. З мене 150 і огірочок;)
Трохи доповнив статтю для зрозумілості. На рахунок закриває текст чи ні, то це вже питання до розміщуючій такий блок :) В демо просто так розташував його, для наочності, ось тут меню по-іншому розташована і, начебто теж все в порядку.
150 - це завжди добре;).
навіщо розраховувати через яку відстань у мене блок поповзе? я краще зроблю так: як тільки прокручу це блок то він поїде відразу мною.
$ (Function () var box = $ ( '# messagelist'); // ваш блок
var top = box.offset (). top - parseFloat (box.css ( 'marginTop'). replace (/ auto /, 0));
$ (Window) .scroll (function () var windowpos = $ (window) .scrollTop ();
if (windowpos
box.css ( 'top', 0);
>
>);
>);
$ (Function () var box = $ ( '# messagelist'); // ваш блок
var top = box.offset (). top;
$ (Window) .scroll (function () var windowpos = $ (window) .scrollTop ();
if (windowpos
>);
>);
Так як функція .offset () в JQ повертає значення включаючи відступи, а marginTop змінить і встановить потрібний.
Верхнє горизонтальне меню сайту розташоване 130px від верху, ширина меню 46px.
Коли сторінка прокручується до заданої висоти, меню ставати fixed, все правильно, як і повинно бути. Але коли воно таким стає воно випадає із загальних блоків, і виходить що сторінка стрибає на ці 46px.
Підкажіть як зробити щоб було плавно без стрибків, точно так само як тут у вас на сайті? Дякуємо!
Все відмінно розписали, тільки я помітив, що в деяких браузерах (маїл, SRWare Iron, Яндекс) у мене правий плаваючий блок при прокручуванні злазить в щільну до стінки браузера вікна. У мене сайт фіксованої ширини. Що можна зробити щоб в деяких браузерах цей блок залишався в колонці правої і при прокручуванні вниз не випадав вправо?
Цей варіант і розрахований на те. щоб блок був завжди на виду, фіксоване позиціонування передбачає прив'язку до вікна браузра, а не до розмітки сайту. Такі витрати варіанта. Треба більше - треба інший скрипт.
Шкода. Весь інет з цим прикладом, а для вузького сайту нічого немає толкового. Знайшов ось такий варіант _habrahabr.kz/blog/programming/567.html але є проблемка інша, при зменшенні браузера (екрану) - блоки постійно Скрол сайт вниз до нескінченності, футер не побачити.
Ви можете до цього скрипту, дописати додаткові умови, які визначали б його позиції в залежності від розмірів вікна браузера, але це вже буде не "простий" плаваючий блок.
Це просто якийсь кошмар! Невже все таки просунуті, що ні у кого не виникло питання "А куди, власне, все це чудо вставляти?". Я, начебто, не перший день в блогінгу, але і до виправлення коди не щодня вдаюся. Перший раз бачу інструкцію без вказівки того, куди все вставляти!
1.В найперший код обернула потрібну міні.
2.CSS просто впихнули в "настройка шаблону" - "додати CSS".
3.Скріпт вставила відразу перед / head, обернувши в відриває / закриває теги "скрипт". Перед цим підключила бібліотеку, додавши туди ж необхідний код з вашого сайту.
Тепер про те що ви робили і чому у вас "НІ ФИГА не працює!"
Реініціалізація скрипта по .resize (mobileFloating ()) не допомагає, тільки перезавантаження сторінки. Мабуть браузер віддає скрипту невірні дані.
Скажіть будь ласка, як пересканіровать dom (вірніше, дізнатися нове положення плаваючого блоку) після того, як над ним (вище по дереву) з'являється новий контент (розгортається / згортається блок типу fieldset)? Зараз виходить так: відкриваю сторінку, на ній є згорнутий fieldset, а нижче вже сітка з плаваючим блоком. При прокручуванні все ок. Однак, якщо я розкриваю fieldset і починаю прокручувати, плаваючий блок фіксується при досягненні межі, встановленої при завантаженні сторінки (тобто щодо тієї висоти до плаваючого блоку, яка була до того, як я розгорнув fieldset).
У скрипт потрібно додати подію при натисканні на fieldset, яке буде змінювати значення змінної на висоту блоку fieldset, щоб плаваючий блок фіксувався після прокрутки fieldset.
Підкажіть будь ласка що змінити що б вийшло так:
допустимо є 2 блоки, зліва і справа, зліва блок довше в 3 рази ніж правий, а правий блок більше вікна браузера. тобто що б побачити кінець правого блоку потрібно прокрутити весь лівий блок (ну це залежить від розміру екрана). Потрібно зробити що б правий блок теж прокручувався разом з лівим, але коли правий блок закінчується він просто липне і не рухається.
Ну як то так, сподіваюся зрозумієте і допоможете :)