it-swarm.com.ru

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

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

278
evanr

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

235
CMS

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

Ответ 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 .

238
Josh Lee

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

39
Colin 't Hart

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

33
Donny V.

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

Вот как я сделал это с помощью 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);
        }
    });
});
9
JohnB

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

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

6
kunde

Как Josh Lee и 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; }.

2
Max Garner

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

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

1
Dan

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

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

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

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

1
pbryd

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

// 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
Josh Russo

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

  $(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
Forge

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

jsfuddle Code

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
brand-it

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

Вот код:

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

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

this ТОЛЬКО CSS Верхняя часть полосы прокрутки экрана. Решил все проблемы с помощью ТОЛЬКО CSS , НЕТ JavaScript, НЕТ JQuery, Нет Работа мозга ( лол ).

Наслаждайтесь моя скрипка : 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 ТОЛЬКО верхняя часть полосы прокрутки экрана

0
weia design

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

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

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

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

0
Amber

В javascript вы можете сделать:

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

У меня есть ссылки настройки в 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)');
    }
});
0
Artistan