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

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

Ответ 1

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

Ответ 2

Вы видели этот пример в 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> 

И простая живая демонстрация.

Запущенная, script -вободная альтернатива - это position: sticky, которая поддерживается в Chrome, Firefox и Safari. См. Статью на HTML5Rocks и demo и Документы Mozilla.

Ответ 3

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

Ответ 4

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

demo: http://htmlpreview.github.io/?https://github.com/donnyv/sticky-panel/blob/master/jquery.stickyPanel/Main.htm

Ответ 5

А вот как без 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>

Ответ 6

Вот как я это сделал с 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 должен начинаться с свойства CSS.

Ответ 8

Как сказал Джош Ли и Colin 't Hart, вы могли бы просто использовать 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; }.

Ответ 9

Мое решение немного подробное, но оно обрабатывает переменное позиционирование из левого края для центрированных макетов.

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

Ответ 10

Вот еще одна версия, чтобы попробовать для тех, у кого проблемы с другими. Он объединяет методы, обсуждаемые в этом дублирующем вопросе, и динамически генерирует требуемые вспомогательные DIVs, поэтому дополнительный 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');

Когда элемент становится липким, код управляет положением оставшегося содержимого, чтобы он не прыгал в промежуток, оставленный липким элементом. Он также возвращает липкий элемент в свое оригинальное нелипкое положение при прокрутке над ним.

Ответ 11

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

Ответ 12

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

Scrollorama имеет функцию "pin it", которая именно то, что я искал.

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

Ответ 13

Информация, предоставленная для ответа на этот другой вопрос, может помочь вам, Эван:

Проверьте, видим ли элемент после прокрутки

В основном вы хотите изменить стиль элемента, чтобы установить его на исправление только после проверки того, что значение document.body.scrollTop равно или больше вершины вашего элемента.

Ответ 14

Принятый ответ работает, но не перемещается назад в предыдущую позицию, если вы прокручиваете над ним. Он всегда прикрепляется к вершине после размещения там.

  $(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, который должен работать, но я не смог заставить его работать. Его примерная страница тоже не работала (для меня).

Ответ 15

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

Вот код:

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

Ответ 16

У меня есть настройка ссылок в 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 [email protected] (Myvendor JavaScript Issue)');
    }
});

Ответ 17

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

код 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();​

Это немного более динамичный способ сделать прокрутку. Это требует некоторой работы, и я в какой-то момент превращу это в плагин, но это то, что я придумал после часа работы.

Ответ 18

В javascript вы можете:

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

Ответ 19

Не точное решение, но отличная альтернатива рассмотрению

this ТОЛЬКО ДЛЯ CSS ТОЧКА экрана прокрутки экрана. Решила всю проблему с помощью ТОЛЬКО CSS, НЕТ JavaScript, НЕТ JQuery, Нет Работа мозга (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">

Поместите контент достаточно долго, чтобы увидеть эффект здесь:) О, и ссылка здесь, потому что он заслужил его кредит

ТОЛЬКО ТОЛЬКО Верхняя панель прокрутки экрана

Ответ 20

Вот пример, который использует плагин jquery-visible: 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");
    });
});

Ответ 21

липкий, пока нижний колонтитул не попадет в 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);

Ответ 22

Вы можете сделать это с помощью метода css() jQuery:

$('#myDiv').css({'position':'sticky','top':'5px'});