Як я можу зробити палицю діви до верхньої частини екрана, коли вона прокручена?


305

Я хотів би створити div, який знаходиться під блоком вмісту, але що після того, як сторінка буде прокручена достатньо, щоб звернутися до її верхньої межі, вона стає фіксованою на місці та прокручує сторінку.


5
Станом на червень 2014 року плагін Sticky-kit jQuery - це один із найпростіших варіантів, що забезпечує надзвичайно низький бар’єр для входу та безліч функцій. Чудове місце для початку, якщо ви шукаєте простий спосіб швидко зійти з землі.
користувач456584


32
Додавання CSS position: sticky; top:0;працює у більшості браузерів у січні 2017 року.
Colin 't Hart

9
Святе лайно, ця position: sticky;річ магічна.
tscizzle

Відповіді:


259

Ви можете використовувати просто css, розташувавши свій елемент як фіксований :

.fixedElement {
    background-color: #c0c0c0;
    position:fixed;
    top:0;
    width:100%;
    z-index:100;
}

Редагувати: Ви повинні мати елемент з абсолютним положенням, коли зміщення прокрутки досягне елемента, його слід змінити на фіксоване, а верхнє положення встановити на нуль.

Ви можете виявити верхнє зміщення прокрутки документа за допомогою функції scrollTop :

$(window).scroll(function(e){ 
  var $el = $('.fixedElement'); 
  var isPositionFixed = ($el.css('position') == 'fixed');
  if ($(this).scrollTop() > 200 && !isPositionFixed){ 
    $el.css({'position': 'fixed', 'top': '0px'}); 
  }
  if ($(this).scrollTop() < 200 && isPositionFixed){
    $el.css({'position': 'static', 'top': '0px'}); 
  } 
});

Коли зміщення прокрутки досягне 200, елемент буде триматися у верхній частині вікна браузера, оскільки він розміщений як фіксований.


4
це не досягає того, за що я йду. Я хотів би, щоб цей елемент починався з 200 пікселів вгорі сторінки (щоб було місце для іншого вмісту), а потім, коли користувач прокручується вниз, фіксується вгорі.
evanr

3
ваше редагування справді заповнює потреби питання, але у вас все ще виникає проблема, коли сторінка знову прокручується до початку. ви могли б після досягнення елемента scrollTop зберегти його десь, і коли сторінка знову потрапить у цю позицію (при прокрутці вгору) змінить css назад на типовий ... ймовірно, краще це зробити з .toggleClass, тоді ...
Sander

9
Це майже все, що коли, але мені довелося видалити фіксовану позицію, коли вікно прокручується назад до вершини. if ($(this).scrollTop() < 200 && $el.css('position') == 'fixed') { $('.fixedElement').css({'position': 'static', 'top': '0px'}); }
Деррік Петцольд

1
@DerrickPetzold Я поставив це у відповідь, досить важливі речі :)
MarioDS

1
new exampleпосилання ви дали настільки чиста і прозора , що я не можу навіть побачити! -_-
sohaiby

245

Ви бачили цей приклад на сторінці випуску Google Code та (лише нещодавно) на сторінці редагування стека Overflow.

Відповідь CMS не скасовує позиціонування під час прокручування назад. Ось безсоромно вкрадений код із Stack Overflow:

function moveScroller() {
    var $anchor = $("#scroller-anchor");
    var $scroller = $('#scroller');

    var move = function() {
        var st = $(window).scrollTop();
        var ot = $anchor.offset().top;
        if(st > ot) {
            $scroller.css({
                position: "fixed",
                top: "0px"
            });
        } else {
            $scroller.css({
                position: "relative",
                top: ""
            });
        }
    };
    $(window).scroll(move);
    move();
}
<div id="sidebar" style="width:270px;"> 
  <div id="scroller-anchor"></div> 
  <div id="scroller" style="margin-top:10px; width:270px"> 
    Scroller Scroller Scroller
  </div>
</div>

<script type="text/javascript"> 
  $(function() {
    moveScroller();
  });
</script> 

І просте демо-версію .

Народжена альтернатива, без сценарію position: sticky, яка підтримується в Chrome, Firefox та Safari. Дивіться статтю про HTML5Rocks та демо та документи Mozilla .


3
Чомусь {scroll: false} ставив мені проблеми (jQuery 1.6.2). Здається, робота без цього. Вилка з пов’язаної демонстрації. Будь-яка ідея, якщо вона служить цілі?
Едді

У мене виникають багато проблем з цим, я все життя не можу повторити, я навіть намагався копіювати демо-версію та її не працює. може хтось посилається на підручник, який надає покрокові інструкції?
Тревор Дапп

2
Це, здається, працює чудово, коли я використовую ту саму версію jQuery, що і демо (1.3.2). У якийсь момент, offsetмабуть, перестали приймати об'єкт як вхід api.jquery.com/offset . @Eddie Ваша модифікація повинна бути безпечною з поточним jQuery.
Graeme

1
Чи є якийсь - небудь причини ви не змогли замінити var d = $("#scroller-anchor").offset().top;з var d = $("#sidebar").offset().top;і позбутися від порожнього скроллер-анкерної DIV все разом? Ось моя вилка демонструє те, про що я говорю.
Майк Дек

@MikeDeck Я підозрюю, що якщо є запаси або прокладки, ви хочете мати можливість контролювати місце розташування скроллера відносно контейнера.
Джош Лі

72

Станом на січень 2017 року та випуск Chrome 56, більшість загальнодоступних браузерів підтримують position: stickyвластивість у CSS.

#thing_to_stick {
  position: sticky;
  top: 0px;
}

робить фокус для мене в Firefox та Chrome.

У Safari все ще потрібно користуватися position: -webkit-sticky.

Поліполи доступні для Internet Explorer та Edge; https://github.com/wilddeer/stickyfill, здається, хороший.


5
Це підтримується в більшості веб-переглядачів, які часто використовуються. Дивіться caniuse.com/#feat=css-sticky По-друге, я віддаю перевагу рішенню, яке може бути зведене до 2 рядків коду до версії, яка вимагає спеціального Javascript. І це також є доказовим. Використовуйте поліфактор, якщо ви переживаєте про сумісність браузера.
Colin 't Hart

1
Не може бути простішим за це :)
закортований

1
Я хотів би додати до цього коментаря, що ми можемо z-індекс: 99999 ;, тому що якщо ні, коли він перейде до вершини, інший вміст буде виведений першим. Але це має бути прийнятим рішенням.
dayanrr91

Просто загорніть його в div з id = "thing_to_stick"
Антон

Просте і легке рішення. І в моєму випадку, звичайно, працює краще, ніж інші рішення.
fsevenm

33

У мене була така ж проблема, як і у вас, і я закінчив робити плагін jQuery, щоб подбати про це. Він фактично вирішує всі проблеми, перелічені тут, плюс додає ще кілька додаткових функцій.

Параметри

stickyPanelSettings = {
    // Use this to set the top margin of the detached panel.
    topPadding: 0,

    // This class is applied when the panel detaches.
    afterDetachCSSClass: "",

    // When set to true the space where the panel was is kept open.
    savePanelSpace: false,

    // Event fires when panel is detached
    // function(detachedPanel, panelSpacer){....}
    onDetached: null,

    // Event fires when panel is reattached
    // function(detachedPanel){....}
    onReAttached: null,

    // Set this using any valid jquery selector to 
    // set the parent of the sticky panel.
    // If set to null then the window object will be used.
    parentSelector: null
};

https://github.com/donnyv/sticky-panel

демонстрація: http://htmlpreview.github.io/?https://github.com/donnyv/sticky-panel/blob/master/jquery.stickyPanel/Main.htm


1
Гей! Дякую! Це чудове рішення, і дякую за спільний доступ, напевно, це заощадило мені багато часу. Це має бути загальноприйнятим рішенням цього питання, оскільки, наскільки я прочитав, це найповніше рішення. В основному, інші не вирішили проблему з початковою X-позицією блоку після позиції: застосовується фіксований стиль. Ваше вирішує цю проблему. Дійсно, велике спасибі!
Marcos Buarque

Привіт, Донні, також люблю ваш плагін (v1.4.1) ... натрапив на одну проблему, блокові елементи втратили свою ширину, якщо жоден не вказаний. Так змінювали його при від'єднанні ... лише встановивши ширину, щоб вона залишалася такою ж. code// від'єднати панель node.css ({"margin": 0, "left": nodeLeft, "top": newNodeTop, "position": "fix", "width": node.width ()}); code
Буде Хенкок

Шукав і випробував багато рішень, і це спрацювало «прямо з коробки». Дивовижна робота! Дякую!
ajtatum

2
@WillHancock Я додав підтримку iPad, виправив помилку оновлення та додав подіїDetached & onReattached. Нові події дадуть вам доступ до панелі & spacerpanel після її від'єднання та повторного приєднання.
Донні В.

4
Також додано параметр parentSelector для підтримки прокрутки дівок.
Донні В.

24

Ось як без jquery (ОНОВЛЕННЯ: дивіться інші відповіді, де тепер це можна зробити лише за допомогою CSS)

var startProductBarPos=-1;
window.onscroll=function(){
  var bar = document.getElementById('nav');
  if(startProductBarPos<0)startProductBarPos=findPosY(bar);

  if(pageYOffset>startProductBarPos){
    bar.style.position='fixed';
    bar.style.top=0;
  }else{
    bar.style.position='relative';
  }

};

function findPosY(obj) {
  var curtop = 0;
  if (typeof (obj.offsetParent) != 'undefined' && obj.offsetParent) {
    while (obj.offsetParent) {
      curtop += obj.offsetTop;
      obj = obj.offsetParent;
    }
    curtop += obj.offsetTop;
  }
  else if (obj.y)
    curtop += obj.y;
  return curtop;
}
* {margin:0;padding:0;}
.nav {
  border: 1px red dashed;
  background: #00ffff;
  text-align:center;
  padding: 21px 0;

  margin: 0 auto;
  z-index:10; 
  width:100%;
  left:0;
  right:0;
}

.header {
  text-align:center;
  padding: 65px 0;
  border: 1px red dashed;
}

.content {
  padding: 500px 0;
  text-align:center;
  border: 1px red dashed;
}
.footer {
  padding: 100px 0;
  text-align:center;
  background: #777;
  border: 1px red dashed;
}
<header class="header">This is a Header</header>
<div id="nav" class="nav">Main Navigation</div>
<div class="content">Hello World!</div>
<footer class="footer">This is a Footer</footer>


4
Дякую! Сьогодні важко знайти рідні рішення JS. Це спрацювало чудово.
Шеррі

Дякую тобі, це прекрасно спрацювало, оскільки jquery суперечив деякому застарілому коду підприємства, який мій проект має
написано

хоч я зіткнувся з проблемою, коли, якщо я прокручую до нижньої частини сторінки, вона автоматично вискакує мене наверх.
співали

@sng Чи робить це моя зразок сторінки?
Джим W каже, що поверніть Моніку

@JimW Я дізнався проблему. Я намагався використовувати його з вертикальною панеллю меню поруч із основним поділом вмісту зліва. Він помиляється, коли ви прокручуєте вниз, оскільки він не може визначити, коли він потрапляє належним чином у нижню частину сторінки. Нарешті я додав рядок коду, щоб встановити висоту дільниці контейнера на розмір екрана вікна слухачеві події прокрутки
відспівано

9

Ось як я це зробив з jquery. Це було спільно з різних відповідей на переповнення стека. Це рішення кешує селектори для більш швидкої продуктивності, а також вирішує проблему "стрибки", коли липкий дів стає липким.

Перевірте це на jsfiddle: http://jsfiddle.net/HQS8s/

CSS:

.stick {
    position: fixed;
    top: 0;
}

JS:

$(document).ready(function() {
    // Cache selectors for faster performance.
    var $window = $(window),
        $mainMenuBar = $('#mainMenuBar'),
        $mainMenuBarAnchor = $('#mainMenuBarAnchor');

    // Run this on scroll events.
    $window.scroll(function() {
        var window_top = $window.scrollTop();
        var div_top = $mainMenuBarAnchor.offset().top;
        if (window_top > div_top) {
            // Make the div sticky.
            $mainMenuBar.addClass('stick');
            $mainMenuBarAnchor.height($mainMenuBar.height());
        }
        else {
            // Unstick the div.
            $mainMenuBar.removeClass('stick');
            $mainMenuBarAnchor.height(0);
        }
    });
});

7

Ось ще один варіант:

JAVASCRIPT

var initTopPosition= $('#myElementToStick').offset().top;   
$(window).scroll(function(){
    if($(window).scrollTop() > initTopPosition)
        $('#myElementToStick').css({'position':'fixed','top':'0px'});
    else
        $('#myElementToStick').css({'position':'absolute','top':initTopPosition+'px'});
});

Ви #myElementToStickповинні почати з position:absoluteCSS власності.


1
Я думаю, що це дуже чисте і просте рішення. Я просто не позиціоную елемент "абсолютний" - це може порушити макет - я б просто встановив його статичним.
Герфрід

4

Як сказали Джош Лі та Колін 'Харт , ви необов'язково можете просто застосувати position: sticky; top: 0;додаток до діву, який ви хочете прокрутити на ...

Крім того, єдине, що вам доведеться зробити, - скопіювати це у верхню частину сторінки або відформатувати його, щоб вмістити його на зовнішній CSS-лист:

<style>
#sticky_div's_name_here { position: sticky; top: 0; }
</style>

Просто замініть #sticky_div's_name_hereна ім'я вашого div, тобто якщо ваш div був <div id="example">би ви поставили #example { position: sticky; top: 0; }.


1

Моє рішення - дещо детальне, але воно обробляє змінне розташування з лівого краю для центральних макетів.

// Ensurs that a element (usually a div) stays on the screen
//   aElementToStick   = The jQuery selector for the element to keep visible
global.makeSticky = function (aElementToStick) {
    var $elementToStick = $(aElementToStick);
    var top = $elementToStick.offset().top;
    var origPosition = $elementToStick.css('position');

    function positionFloater(a$Win) {
        // Set the original position to allow the browser to adjust the horizontal position
        $elementToStick.css('position', origPosition);

        // Test how far down the page is scrolled
        var scrollTop = a$Win.scrollTop();
        // If the page is scrolled passed the top of the element make it stick to the top of the screen
        if (top < scrollTop) {
            // Get the horizontal position
            var left = $elementToStick.offset().left;
            // Set the positioning as fixed to hold it's position
            $elementToStick.css('position', 'fixed');
            // Reuse the horizontal positioning
            $elementToStick.css('left', left);
            // Hold the element at the top of the screen
            $elementToStick.css('top', 0);
        }
    }

    // Perform initial positioning
    positionFloater($(window));

    // Reposition when the window resizes
    $(window).resize(function (e) {
        positionFloater($(this));
    });

    // Reposition when the window scrolls
    $(window).scroll(function (e) {
        positionFloater($(this));
    });
};

1

Ось ще одна версія, щоб спробувати для тих, хто має проблеми з іншими. Він об'єднує методи, обговорені в цьому повторюваному запитанні , та генерує необхідні помічники DIV динамічно, так що зайвий HTML не потрібен.

CSS:

.sticky { position:fixed; top:0; }

JQuery:

function make_sticky(id) {
    var e = $(id);
    var w = $(window);
    $('<div/>').insertBefore(id);
    $('<div/>').hide().css('height',e.outerHeight()).insertAfter(id);
    var n = e.next();
    var p = e.prev();
    function sticky_relocate() {
      var window_top = w.scrollTop();
      var div_top = p.offset().top;
      if (window_top > div_top) {
        e.addClass('sticky');
        n.show();
      } else {
        e.removeClass('sticky');
        n.hide();
      }
    }
    w.scroll(sticky_relocate);
    sticky_relocate();
}

Щоб зробити елемент липким, зробіть:

make_sticky('#sticky-elem-id');

Коли елемент стає клейким, код керує положенням вмісту, що залишився, щоб не стрибнути у прогалину, залишену липким елементом. Він також повертає липкий елемент у початкове не липке положення при прокручуванні назад над ним.


Ваш підхід дуже схожий на підхід JohnB . Враховуючи ваші відмінності від цієї відповіді, мені цікаво (1) Чи є перевага у використанні другого "помічника діва" (замість всього 1, як використовує JohnB), та (2) Чи є перевага використання skriv () та show () замість того, щоб просто встановити висоту помічника Div (як це робить JohnB)? Можливо, різниця у виконанні? Поки що мені не вдалося розрізнити відмінності, але, можливо, певні сценарії мали б відмінності (наприклад, із залученням вбудованих елементів чи чогось іншого), тому я запитую. Дякую.
Джейсон Френк

1

Ось розширена версія відповіді Джоша Лі. Якщо ви хочете, щоб div знаходився на бічній панелі праворуч і плавав у межах діапазону (тобто, вам потрібно вказати верхні та нижні позиції якоря). Він також виправляє помилку, коли ви переглядаєте це на мобільних пристроях (вам потрібно перевірити положення прокрутки ліворуч, інакше дів зміститься з екрану).

function moveScroller() {
    var move = function() {
        var st = $(window).scrollTop();
        var sl = $(window).scrollLeft();
        var ot = $("#scroller-anchor-top").offset().top;
        var ol = $("#scroller-anchor-top").offset().left;
        var bt = $("#scroller-anchor-bottom").offset().top;
        var s = $("#scroller");
        if(st > ot) {
            if (st < bt - 280) //280px is the approx. height for the sticky div
            {
                s.css({
                    position: "fixed",
                    top: "0px",
                    left: ol-sl
                }); 
            }
            else
            {
                s.css({
                    position: "fixed",
                    top: bt-st-280,
                    left: ol-sl
                }); 
            }
        } else {
            s.css({
                position: "relative",
                top: "",
                left: ""
            });

        }
    };
    $(window).scroll(move);
    move();
}

1

Я натрапив на це, шукаючи те саме. Я знаю, що це давнє запитання, але я подумав, що запропоную більш пізню відповідь.

У Scrollorama є функція 'pin it', яка саме те, що я шукав.

http://johnpolacek.github.io/scrollorama/


0

Інформація, надана для відповіді на це інше питання, може вам допомогти, Еван:

Перевірте, чи елемент видно після прокрутки

Ви в основному хочете змінити стиль елемента, щоб встановити його фіксованим лише після того, як перевірили, що значення document.body.scrollTop дорівнює або перевищує верхню частину вашого елемента.


0

Прийнята відповідь працює, але не повертається до попередньої позиції, якщо прокрутити вище. Він завжди приклеюється до верху після розміщення туди.

  $(window).scroll(function(e) {
    $el = $('.fixedElement');
    if ($(this).scrollTop() > 42 && $el.css('position') != 'fixed') {
      $('.fixedElement').css( 'position': 'fixed', 'top': '0px');

    } else if ($(this).scrollTop() < 42 && $el.css('position') != 'relative') {
      $('.fixedElement').css( 'relative': 'fixed', 'top': '42px');
//this was just my previous position/formating
    }
  });

Відповідь jleedev могла б спрацювати, але я не зміг змусити її працювати. Його сторінка-приклад також не працювала (для мене).


0

Ви можете додати 3 додаткові рядки, тож коли користувач прокрутить назад до вершини, div залишиться на своєму старому місці:

Ось код:

if ($(this).scrollTop() < 200 && $el.css('position') == 'fixed'){
    $('.fixedElement').css({'position': 'relative', 'top': '200px'});
}

0

У мене є налаштування посилань у діві, тому це вертикальний список літер та цифр.

#links {
    float:left;
    font-size:9pt;
    margin-left:0.5em;
    margin-right:1em;
    position:fixed;
    text-align:center;
    width:0.8em;
}

Потім я налаштовую цю зручну функцію jQuery, щоб зберегти завантажену позицію, а потім змінити положення на фіксоване при прокрутці за межі цієї позиції.

ПРИМІТКА. Це працює лише в тому випадку, якщо посилання видно при завантаженні сторінки !!

var listposition=false;
jQuery(function(){
     try{
        ///// stick the list links to top of page when scrolling
        listposition = jQuery('#links').css({'position': 'static', 'top': '0px'}).position();
        console.log(listposition);
        $(window).scroll(function(e){
            $top = $(this).scrollTop();
            $el = jQuery('#links');
            //if(typeof(console)!='undefined'){
            //    console.log(listposition.top,$top);
            //}
            if ($top > listposition.top && $el.css('position') != 'fixed'){
                $el.css({'position': 'fixed', 'top': '0px'});
            }
            else if ($top < listposition.top && $el.css('position') == 'fixed'){
                $el.css({'position': 'static'});
            }
        });

    } catch(e) {
        alert('Please vendor admin@mydomain.com (Myvendor JavaScript Issue)');
    }
});

0

Я використовував деякі роботи вище, щоб створити цю техніку. Я трохи її покращив і думав, що поділюсь своєю роботою. Сподіваюсь, це допомагає.

Код jsfuddle

function scrollErrorMessageToTop() {
    var flash_error = jQuery('#flash_error');
    var flash_position = flash_error.position();

    function lockErrorMessageToTop() {
        var place_holder = jQuery("#place_holder");
        if (jQuery(this).scrollTop() > flash_position.top && flash_error.attr("position") != "fixed") {
            flash_error.css({
                'position': 'fixed',
                'top': "0px",
                "width": flash_error.width(),
                "z-index": "1"
            });
            place_holder.css("display", "");
        } else {
            flash_error.css('position', '');
            place_holder.css("display", "none");
        }

    }
    if (flash_error.length > 0) {
        lockErrorMessageToTop();

        jQuery("#flash_error").after(jQuery("<div id='place_holder'>"));
        var place_holder = jQuery("#place_holder");
        place_holder.css({
            "height": flash_error.height(),
            "display": "none"
        });
        jQuery(window).scroll(function(e) {
            lockErrorMessageToTop();
        });
    }
}
scrollErrorMessageToTop();​

Це трохи динамічніший спосіб зробити прокрутку. Для цього потрібна певна робота, і я в якийсь момент перетворять це на плагінг, але це те, що я придумав після години роботи.


0

У javascript ви можете:

var element = document.getElementById("myid");
element.style.position = "fixed";
element.style.top = "0%";

0

Не точне рішення, але чудова альтернатива

цей CSS ТОЛЬКО у верхній частині панелі прокрутки екрана . Вирішено всю проблему з ТОЛЬКО CSS , NO JavaScript, NO JQuery, No Brain робота ( lol ).

Насолоджуйтесь моєю загадкою : D усі коди тут включені :)

CSS

#menu {
position: fixed;
height: 60px;
width: 100%;
top: 0;
left: 0;
border-top: 5px solid #a1cb2f;
background: #fff;
-moz-box-shadow: 0 2px 3px 0px rgba(0, 0, 0, 0.16);
-webkit-box-shadow: 0 2px 3px 0px rgba(0, 0, 0, 0.16);
box-shadow: 0 2px 3px 0px rgba(0, 0, 0, 0.16);
z-index: 999999;
}

.w {
    width: 900px;
    margin: 0 auto;
    margin-bottom: 40px;
}<br type="_moz">

Розміщуйте вміст досить довго, щоб ви могли побачити ефект тут :) О, і довідка також є там, адже він заслуговує на свою заслугу

ТОЛЬКО CSS У верхній частині панелі прокрутки екрану


Трохи офтопік;)
Tokk

Я не проти хорошого рішення, але код у вашій відповіді дає спосіб скласти щось на зразок меню, яке завжди дотримується зверху. Але це не було питання ...
Tokk

ви просто виправляєте div і не робите нічого липкого при прокручуванні.
йогіхостінг

0

Ось приклад, який використовує плагін-видимий jquery: http://jsfiddle.net/711p4em4/ .

HTML:

<div class = "wrapper">
    <header>Header</header>
    <main>
        <nav>Stick to top</nav>
        Content
    </main>
    <footer>Footer</footer>
</div>

CSS:

* {
    margin: 0;
    padding: 0;
}

body {
    background-color: #e2e2e2;
}

.wrapper > header,
.wrapper > footer {
    font: 20px/2 Sans-Serif;
    text-align: center;
    background-color: #0040FF;
    color: #fff;
}

.wrapper > main {
    position: relative;
    height: 500px;
    background-color: #5e5e5e;
    font: 20px/500px Sans-Serif;
    color: #fff;
    text-align: center;
    padding-top: 40px;
}

.wrapper > main > nav {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    font: 20px/2 Sans-Serif;
    color: #fff;
    text-align: center;
    background-color: #FFBF00;
}

.wrapper > main > nav.fixed {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
}

JS (включайте плагін, видимий jquery):

(function($){

    /**
     * Copyright 2012, Digital Fusion
     * Licensed under the MIT license.
     * http://teamdf.com/jquery-plugins/license/
     *
     * @author Sam Sehnert
     * @desc A small plugin that checks whether elements are within
     *       the user visible viewport of a web browser.
     *       only accounts for vertical position, not horizontal.
     */
    var $w = $(window);
    $.fn.visible = function(partial,hidden,direction){

        if (this.length < 1)
            return;

        var $t        = this.length > 1 ? this.eq(0) : this,
            t         = $t.get(0),
            vpWidth   = $w.width(),
            vpHeight  = $w.height(),
            direction = (direction) ? direction : 'both',
            clientSize = hidden === true ? t.offsetWidth * t.offsetHeight : true;

        if (typeof t.getBoundingClientRect === 'function'){

            // Use this native browser method, if available.
            var rec = t.getBoundingClientRect(),
                tViz = rec.top    >= 0 && rec.top    <  vpHeight,
                bViz = rec.bottom >  0 && rec.bottom <= vpHeight,
                lViz = rec.left   >= 0 && rec.left   <  vpWidth,
                rViz = rec.right  >  0 && rec.right  <= vpWidth,
                vVisible   = partial ? tViz || bViz : tViz && bViz,
                hVisible   = partial ? lViz || rViz : lViz && rViz;

            if(direction === 'both')
                return clientSize && vVisible && hVisible;
            else if(direction === 'vertical')
                return clientSize && vVisible;
            else if(direction === 'horizontal')
                return clientSize && hVisible;
        } else {

            var viewTop         = $w.scrollTop(),
                viewBottom      = viewTop + vpHeight,
                viewLeft        = $w.scrollLeft(),
                viewRight       = viewLeft + vpWidth,
                offset          = $t.offset(),
                _top            = offset.top,
                _bottom         = _top + $t.height(),
                _left           = offset.left,
                _right          = _left + $t.width(),
                compareTop      = partial === true ? _bottom : _top,
                compareBottom   = partial === true ? _top : _bottom,
                compareLeft     = partial === true ? _right : _left,
                compareRight    = partial === true ? _left : _right;

            if(direction === 'both')
                return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop)) && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
            else if(direction === 'vertical')
                return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop));
            else if(direction === 'horizontal')
                return !!clientSize && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
        }
    };

})(jQuery);

$(function() {
    $(window).scroll(function() {
        $(".wrapper > header").visible(true) ?
            $(".wrapper > main > nav").removeClass("fixed") :
            $(".wrapper > main > nav").addClass("fixed");
    });
});

-1

липкий, поки нижній колонтитул не потрапить у діву:

function stickyCostSummary() {
    var stickySummary = $('.sticky-cost-summary');
    var scrollCostSummaryDivPosition = $(window).scrollTop();
    var footerHeight = $('#footer').height();
    var documentHeight = $(document).height();
    var costSummaryHeight = stickySummary.height();
    var headerHeight = 83;
    var footerMargin = 10;
    var scrollHeight = 252;
    var footerPosition = $('#footer').offset().top;

    if (scrollCostSummaryDivPosition > scrollHeight && scrollCostSummaryDivPosition <= (documentHeight - footerHeight - costSummaryHeight - headerHeight - footerMargin)) {
        stickySummary.removeAttr('style');
        stickySummary.addClass('fixed');

    } else if (scrollCostSummaryDivPosition > (documentHeight - footerHeight - costSummaryHeight - headerHeight - footerMargin)) {
        stickySummary.removeClass('fixed');
        stickySummary.css({
          "position" : "absolute",
          "top" : (documentHeight - footerHeight - costSummaryHeight - headerHeight - footerMargin - scrollHeight) + "px"
      });
    } else {
        stickySummary.removeClass('fixed');
        stickySummary.css({
            "position" : "absolute",
            "top" : "0"
        });
    }
}

$window.scroll(stickyCostSummary);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.