Как я могу сделать div палку в верхней части экрана, как только он был прокручен?
Я хотел бы создать div, который расположен под блоком контента, но как только страница была прокручена достаточно, чтобы связаться с ее верхней границей, становится фиксированным на месте и прокручивается со страницей. Я знаю, я видел по крайней мере один пример в интернете, но я не помню его хоть убей.
какие мысли?
21 ответ:
Вы можете использовать просто css, позиционируя свой элемент как основные:
.fixedElement { background-color: #c0c0c0; position:fixed; top:0; width:100%; z-index:100; }
Edit: у вас должен быть элемент с абсолютной позицией, как только смещение прокрутки достигнет элемента, оно должно быть изменено на фиксированное, а верхняя позиция должна быть установлена на ноль.
вы можете обнаружить смещение верхней прокрутки документа с помощью 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, элемент будет ручки в верхней части окна браузера, потому что это исправлено.
вы видели этот пример в коде Google страница и (только недавно) на странице редактирования переполнения стека.
ответ CMS не отменяет позиционирование при прокрутке вверх. Вот бесстыдно украденный код из переполнения стека:
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 docs.
У меня была та же проблема, что и у вас, и в итоге я сделал плагин 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 };
по состоянию на январь 2017 года и выпуск Chrome 56, большинство браузеров в общем использовании поддерживают
position: sticky
свойство в CSS.#thing_to_stick { position: sticky; top: 0px; }
делает трюк для меня в Firefox и Chrome.
в Safari вам все равно нужно использовать
position: -webkit-sticky
.Polyfills доступны для Internet Explorer и Edge;https://github.com/wilddeer/stickyfill кажется, хороший.
и без 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>
вот как я сделал это с 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); } }); });
вот еще один вариант:
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.
мое решение немного многословно, но оно обрабатывает переменное позиционирование с левого края для центрированных макетов.
// 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)); }); };
вот еще одна версия, чтобы попробовать для тех, кто имеет проблемы с другим. Он объединяет методы, обсуждаемые в это дубликат вопрос, и генерирует необходимые вспомогательные дивы динамически, поэтому не требуется дополнительный 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');
когда элемент становится липким, код управляет положением оставшегося содержимого, чтобы сохранить его прыгаем в щель, оставленную липким элементом. Он также возвращает липкий элемент в исходное нелипкое положение при прокрутке назад над ним.
вот Расширенная версия ответа Джоша ли. Если вы хотите, чтобы 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(); }
я наткнулся на это, когда искал то же самое. Я знаю, что это старый вопрос, но я думал, что предложу более свежий ответ.
Scrollorama имеет функцию "pin it", которая является именно тем, что я искал.
как Джош Ли и Колин 'т Харт сказали, вы могли бы дополнительно просто использовать
position: sticky; top: 0;
применение к div, в котором вы хотите прокручивать...кроме того, единственное, что вам нужно будет сделать, это скопировать это в верхнюю часть страницы или отформатировать его, чтобы вписаться во внешний лист CSS:
<style> #sticky_div's_name_here { position: sticky; top: 0; } </style>
просто заменить
#sticky_div's_name_here
С именем вашего div, т. е. если ваш див был<div id="example">
ты бы поставил#example { position: sticky; top: 0; }
.
информация, предоставленная для ответа на этот другой вопрос, может помочь вам, Эван:
Проверьте, виден ли элемент после прокрутки
вы в основном хотите изменить стиль элемента, чтобы установить его фиксированным только после проверки этого документа.тело.значение scrollTop равно или больше верхней части элемента.
принятый ответ работает, но не возвращается в предыдущее положение, если вы прокручиваете его выше. Он всегда прилипает к вершине после размещения там.
$(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, который должен был работать, но я не смог заставить его работать. Его примерная страница также не работала (для меня).
вы можете добавить 3 дополнительных строки, поэтому, когда пользователь прокрутит назад к началу, div будет придерживаться своего старого места:
вот код:
if ($(this).scrollTop() < 200 && $el.css('position') == 'fixed'){ $('.fixedElement').css({'position': 'relative', 'top': '200px'}); }
у меня есть настройки ссылок в 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)'); } });
я использовал некоторые работы, чтобы создать эту технологию. Я немного улучшил его и подумал, что поделюсь своей работой. Надеюсь, это поможет.
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();
Это немного более динамичный способ сделать свиток. Это требует некоторой работы, и я в какой-то момент превращу это в затыкание, но это то, что я придумал после часа работы.
в JavaScript, вы можете сделать:
var element = document.getElementById("myid"); element.style.position = "fixed"; element.style.top = "0%";
не точное решение, но отличная альтернатива для рассмотрения
этой 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">
поместить содержимое долго достаточно, чтобы вы могли увидеть эффект здесь :) О, и ссылка там тоже, за то, что он заслуживает его заслуга
вот пример, который использует плагин 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-visible):
(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"); }); });
липкий, пока нижний колонтитул не попадает в 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);