javascript - propiedades - manual html div
¿Cómo puedo hacer que un div se adhiera a la parte superior de la pantalla una vez que se ha desplazado? (21)
A partir de enero de 2017 y el lanzamiento de Chrome 56, la mayoría de los navegadores de uso común admiten la position: sticky
propiedad position: sticky
en CSS.
#thing_to_stick {
position: sticky;
top: 0px;
}
hace el truco para mí en Firefox y Chrome.
En Safari todavía necesitas usar la position: -webkit-sticky
.
Polyfills está disponible para Internet Explorer y Edge; https://github.com/wilddeer/stickyfill parece ser una buena.
Me gustaría crear un div, que se encuentra debajo de un bloque de contenido, pero que una vez que la página se ha desplazado lo suficiente como para contactar con su límite superior, se fija en su lugar y se desplaza con la página. Sé que he visto al menos un ejemplo de esto en línea, pero no puedo recordarlo por el resto de mi vida.
¿Alguna idea?
Aquí hay otra opción:
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''});
});
Su #myElementToStick
debe comenzar con la position:absolute
propiedad position:absolute
CSS.
Aquí hay un ejemplo que utiliza el complemento 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 (incluye plugin 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");
});
});
Aquí hay una versión extendida de la respuesta de Josh Lee. Si desea que el div esté en la barra lateral a la derecha y flote dentro de un rango (es decir, debe especificar las posiciones de anclaje superior e inferior). También corrige un error cuando lo ves en dispositivos móviles (necesitas verificar la posición de desplazamiento a la izquierda, de lo contrario el div se moverá fuera de la pantalla).
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();
}
Aquí hay una versión más para probar para aquellos que tienen problemas con los demás. Reúne las técnicas analizadas en esta pregunta duplicada y genera los DIV auxiliares necesarios de forma dinámica, por lo que no se requiere HTML adicional.
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();
}
Para hacer un elemento pegajoso, haz:
make_sticky(''#sticky-elem-id'');
Cuando el elemento se vuelve pegajoso, el código administra la posición del contenido restante para evitar que salte al espacio que deja el elemento pegajoso. También devuelve el elemento adhesivo a su posición original no adhesiva cuando se desplaza hacia atrás sobre él.
Así es como lo hice con jquery. Todo esto fue improvisado a partir de varias respuestas en el desbordamiento de pila. Esta solución almacena en caché los selectores para un rendimiento más rápido y también resuelve el problema del "salto" cuando el div sticky se vuelve pegajoso.
Compruébelo en 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);
}
});
});
Como y Colin ''t Hart han dicho, opcionalmente podrías usar la position: sticky; top: 0;
position: sticky; top: 0;
Aplicando a la div que desea el desplazamiento en ...
Además, lo único que tendrás que hacer es copiar esto en la parte superior de tu página o formatearlo para que quepa en una hoja de CSS externa:
<style>
#sticky_div''s_name_here { position: sticky; top: 0; }
</style>
Simplemente reemplaza #sticky_div''s_name_here
con el nombre de tu div, es decir, si tu div era <div id="example">
pondrías #example { position: sticky; top: 0; }
#example { position: sticky; top: 0; }
#example { position: sticky; top: 0; }
.
En javascript puedes hacer:
var element = document.getElementById("myid");
element.style.position = "fixed";
element.style.top = "0%";
Ha visto este ejemplo en la página de problemas de Google Code y (solo recientemente) en la página de edición de .
La respuesta de CMS no revierte el posicionamiento cuando se desplaza hacia atrás. Aquí está el código descaradamente robado de :
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>
Y una simple demostración en vivo .
Una alternativa incipiente y sin secuencias de comandos es position: sticky
, que se admite en Chrome, Firefox y Safari. Vea el artículo sobre HTML5Rocks y demo , y documentos de Mozilla .
La información provista para responder esta otra pregunta puede ser de ayuda para usted, Evan:
Compruebe si el elemento es visible después de desplazarse
Básicamente, desea modificar el estilo del elemento para configurarlo como fijo solo después de haber verificado que el valor document.body.scrollTop es igual o mayor que la parte superior de su elemento.
La respuesta aceptada funciona pero no vuelve a la posición anterior si se desplaza sobre ella. Siempre está pegado a la parte superior después de ser colocado allí.
$(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
}
});
La respuesta de jleedev funcionaba, pero no pude hacerlo funcionar. Su página de ejemplo tampoco funcionó (para mí).
Me encontré con esto cuando buscaba lo mismo. Sé que es una pregunta antigua, pero pensé que ofrecería una respuesta más reciente.
Scrollorama tiene una función ''pin it'' que es justo lo que estaba buscando.
Mi solución es un poco detallada, pero maneja el posicionamiento variable desde el borde izquierdo para diseños centrados.
// 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));
});
};
Podría usar simplemente css, posicionando su elemento como fixed :
.fixedElement {
background-color: #c0c0c0;
position:fixed;
top:0;
width:100%;
z-index:100;
}
Edición: debe tener el elemento con la posición absoluta, una vez que el desplazamiento de desplazamiento haya alcanzado el elemento, debe cambiarse a fijo y la posición superior debe establecerse en cero.
Puede detectar el desplazamiento de desplazamiento superior del documento con la función 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''});
}
});
Cuando el desplazamiento de desplazamiento llegó a 200, el elemento se pegará a la parte superior de la ventana del navegador, porque se coloca como fijo.
Puede agregar 3 filas adicionales para que cuando el usuario se desplace hacia la parte superior, el div se quede en su lugar anterior:
Aquí está el código:
if ($(this).scrollTop() < 200 && $el.css(''position'') == ''fixed''){
$(''.fixedElement'').css({''position'': ''relative'', ''top'': ''200px''});
}
Tengo la configuración de enlaces en un div, por lo que es una lista vertical de enlaces de letras y números.
#links {
float:left;
font-size:9pt;
margin-left:0.5em;
margin-right:1em;
position:fixed;
text-align:center;
width:0.8em;
}
Luego configuro esta práctica función jQuery para guardar la posición cargada y luego la posición se fija en fija cuando se desplaza más allá de esa posición.
NOTA: esto solo funciona si los enlaces son visibles en la carga de la página!
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)'');
}
});
Tuve el mismo problema que tú y terminé haciendo un plugin de jQuery para cuidarlo. En realidad resuelve todos los problemas que las personas han enumerado aquí, además de que también agrega un par de características opcionales.
Opciones
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
};
Utilicé algunos de los trabajos anteriores para crear esta tecnología. Lo mejoré un poco y pensé en compartir mi trabajo. Espero que esto ayude.
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();
Esto es un poco más dinámico de una manera de hacer el desplazamiento. Necesita algo de trabajo y en algún momento convertiré esto en una conexión, pero esto es lo que se me ocurrió después de una hora de trabajo.
Y así es como sin jquery (ACTUALIZACIÓN: vea otras respuestas donde ahora puede hacer esto solo con 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>
pegajoso hasta que el pie de página golpea el 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);
No es una solución exacta pero una gran alternativa a considerar
Este CSS SOLAMENTE es la barra de desplazamiento de la pantalla . Resuelto todos los problemas con SOLO CSS , NO JavaScript, NO JQuery, No Brain trabajo ( lol ).
Disfruta de mi violín : D todos los códigos están incluidos allí :)
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">
Coloque el contenido el tiempo suficiente para que pueda ver el efecto aquí :) Ah, y la referencia también está ahí, por el hecho de que merece su crédito.
SOLO CSS Arriba de la barra de desplazamiento de la pantalla