Как сделать, чтобы div переместился в верхнюю часть экрана после того, как он будет прокручен?


305

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


5
По состоянию на июнь 2014 года плагин Sticky-kit jQuery - один из самых простых вариантов, обеспечивающий чрезвычайно низкий барьер для входа и множество функций. Отличное место для начала, если вы ищете простой способ быстро оторваться от земли.
user456584


33
Добавление CSS position: sticky; top:0;работает в большинстве браузеров в январе 2017 года.
Colin 't Hart

9
Святое дерьмо, эта position: sticky;вещь волшебная.
tscizzle

Ответы:


260

Вы можете использовать просто 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
Это почти то же самое, что при использовании, но мне пришлось убрать фиксированное положение, когда окно is прокручивается назад к вершине. if ($(this).scrollTop() < 200 && $el.css('position') == 'fixed') { $('.fixedElement').css({'position': 'static', 'top': '0px'}); }
Деррик Петцольд,

1
@DerrickPetzold Я положил это в ответ, довольно важные вещи :)
MarioDS

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

245

Вы видели этот пример на странице проблемы Google Code и (только недавно) на странице редактирования Stack 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.
Грэм

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 Во-вторых, я предпочитаю решение, которое может быть сведено к двум строкам кода, к версии, которая требует пользовательского Javascript. И это тоже будущее. Используйте полифилл, если вы беспокоитесь о совместимости браузера.
Colin 't Hart

1
Не может быть проще, чем это :)
старт

1
Я хотел бы добавить к этому комментарию, что мы можем z-index: 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-позицией блока после позиции: применяется фиксированный стиль. Ваш решает эту проблему. Действительно, большое спасибо!
Маркос Бурке

Эй, Донни, также любите твой плагин (v1.4.1) ... действительно сталкивался с одной проблемой, блочные элементы потеряли свою ширину, если ни один не был указан. Так что измените его при отсоединении ... только установив ширину, чтобы она осталась прежней. code// отсоединить панель node.css ({"margin": 0, «left»: nodeLeft, «top»: newNodeTop, «position»: «fixed», «width»: node.width ()}); code
Уилл Хэнкок

Искал и пробовал много решений, и это работало "прямо из коробки". Потрясающая работа! Спасибо!
ajtatum

2
@WillHancock Я добавил поддержку iPad, исправил ошибку обновления и добавил события onDetached и onReattached. Новые события предоставят вам доступ к панели и разделительной панели после ее отсоединения и повторного подключения.
Донни В.

4
Также добавлена ​​опция parentSelector для поддержки прокрутки div.
Донни В.

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

хотя я сталкиваюсь с проблемой, когда, если я прокручиваю до нижней части страницы, она автоматически возвращает меня наверх.
sng

@sng Делает ли это мой образец страницы?
Джим В. говорит восстановить Монику

@JimW Я выяснил проблему. Я пытался использовать его с вертикальной строкой меню рядом с основным содержимым div слева. При прокрутке вниз возникали ошибки, так как он не может определить, правильно ли он попадает в нижнюю часть страницы. Я закончил тем, что добавил строку кода, чтобы установить высоту div контейнера в размер экрана окна для прослушивателя события прокрутки
sng

9

Вот как я это сделал с помощью jquery. Все это было объединено различными ответами на переполнение стека. Это решение кэширует селекторы для более быстрой работы, а также решает проблему «скачка», когда липкий div становится липким.

Проверьте это на 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
Я думаю, что это очень чистое и простое решение. Я просто не стал бы позиционировать элемент «absolute» - это может нарушить компоновку - я бы просто установил его на static.
Gerfried

4

Как сказали Джош Ли и Колин Тарт , вы можете просто использоватьposition: sticky; top: 0; подать заявку на div, который вы хотите прокрутить в ...

Кроме того, единственное, что вам нужно сделать, это скопировать это в верхнюю часть вашей страницы или отформатировать так, чтобы оно вписывалось во внешний лист 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) Есть ли преимущество в использовании второго «вспомогательного div» (вместо 1, как использует JohnB), и (2) Есть ли преимущество в использовании hide () и show () вместо того, чтобы просто устанавливать высоту вспомогательного элемента div (как это делает JohnB)? Возможно разница в производительности? До сих пор я не мог различить различия, но, возможно, некоторые сценарии будут иметь различия (например, могут быть встроенные элементы или что-то в этом роде), поэтому я и спрашиваю. Спасибо.
Джейсон Франк

1

Вот расширенная версия ответа Джоша Ли. Если вы хотите, чтобы div находился на боковой панели справа и перемещался в пределах диапазона (т. Е. Вам нужно указать верхнюю и нижнюю позиции привязки). Это также исправляет ошибку, когда вы просматриваете это на мобильных устройствах (вам нужно проверить левую позицию прокрутки, иначе 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 есть функция «закрепить», и это именно то, что я искал.

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
    }
  });

Ответ Джлидева должен был сработать, но я не смог заставить его работать. Его страница с примером также не сработала (для меня).


0

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

Вот код:

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

0

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

#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, нет Brain работы ( лол ).

Наслаждайся моей скрипкой : 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

вы просто исправляете 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

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

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.