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

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

Ответы [ 22 ]

238 голосов
/ 28 января 2010

Вы видели этот пример на странице кода Google Code и (только недавно) на странице редактирования переполнения стека.

Ответ 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 и demo и Mozilla docs .

234 голосов
/ 01 августа 2009

Вы можете просто использовать css, позиционируя свой элемент как fixed :

.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, элемент будет придерживаться в верхней части окна браузера, поскольку размещается как фиксированный.

41 голосов
/ 23 января 2017

По состоянию на январь 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 кажется хорошим.

33 голосов
/ 19 января 2011

У меня была та же проблема, что и у вас, и в итоге я создал плагин 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

22 голосов
/ 05 июля 2013

А вот как без 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>
9 голосов
/ 26 марта 2013

Вот как я это сделал с помощью 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);
        }
    });
});
6 голосов
/ 13 сентября 2013

Вот еще один вариант:

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:absolute свойства CSS.

2 голосов
/ 27 июня 2017

Как сказали Джош Ли и Колин Тарт , вы можете по желанию просто использовать 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 голос
/ 14 апреля 2015

Я сталкивался с этим, когда искал то же самое. Я знаю, что это старый вопрос, но я подумал, что предложу более свежий ответ.

У Scrollorama есть функция «закрепить», и это именно то, что я искал.

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

1 голос
/ 23 декабря 2013

Вот расширенная версия ответа Джоша Ли. Если вы хотите, чтобы 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();
}
...