Lo que estoy tratando de hacer es que si hace clic en un botón, se desplace hacia abajo (suavemente) a un div específico en la página.
Lo que necesito es que si haces clic en el botón, se desplaza suavemente hasta el div 'segundo'.
.first {
width: 100%;
height: 1000px;
background: #ccc;
}
.second {
width: 100%;
height: 1000px;
background: #999;
}
<div class="first"><button type="button">Click Me!</button></div>
<div class="second">Hi</div>
javascript
jquery
Erik Fischer
fuente
fuente
Respuestas:
hacer:
$("button").click(function() { $('html,body').animate({ scrollTop: $(".second").offset().top}, 'slow'); });
Jsfiddle actualizado
fuente
Hay muchos ejemplos de desplazamiento suave utilizando bibliotecas JS como jQuery, Mootools, Prototype, etc.
El siguiente ejemplo está en JavaScript puro. Si no tiene jQuery / Mootools / Prototype en la página o no desea sobrecargar la página con bibliotecas JS pesadas, el ejemplo será de ayuda.
http://jsfiddle.net/rjSfP/
Parte HTML:
<div class="first"><button type="button" onclick="smoothScroll(document.getElementById('second'))">Click Me!</button></div> <div class="second" id="second">Hi</div>
Parte CSS:
.first { width: 100%; height: 1000px; background: #ccc; } .second { width: 100%; height: 1000px; background: #999; }
Parte JS:
window.smoothScroll = function(target) { var scrollContainer = target; do { //find scroll container scrollContainer = scrollContainer.parentNode; if (!scrollContainer) return; scrollContainer.scrollTop += 1; } while (scrollContainer.scrollTop == 0); var targetY = 0; do { //find the top of target relatively to the container if (target == scrollContainer) break; targetY += target.offsetTop; } while (target = target.offsetParent); scroll = function(c, a, b, i) { i++; if (i > 30) return; c.scrollTop = a + (b - a) / 30 * i; setTimeout(function(){ scroll(c, a, b, i); }, 20); } // start scrolling scroll(scrollContainer, scrollContainer.scrollTop, targetY, 0); }
fuente
Jugué un poco con la respuesta de Nico y me sentí nervioso. Investigué un poco y encontré
window.requestAnimationFrame
cuál es una función que se llama en cada ciclo de repintado. Esto permite una animación más limpia. Todavía estoy tratando de perfeccionar los buenos valores predeterminados para el tamaño del paso, pero para mi ejemplo, las cosas se ven bastante bien con esta implementación.var smoothScroll = function(elementId) { var MIN_PIXELS_PER_STEP = 16; var MAX_SCROLL_STEPS = 30; var target = document.getElementById(elementId); var scrollContainer = target; do { scrollContainer = scrollContainer.parentNode; if (!scrollContainer) return; scrollContainer.scrollTop += 1; } while (scrollContainer.scrollTop == 0); var targetY = 0; do { if (target == scrollContainer) break; targetY += target.offsetTop; } while (target = target.offsetParent); var pixelsPerStep = Math.max(MIN_PIXELS_PER_STEP, (targetY - scrollContainer.scrollTop) / MAX_SCROLL_STEPS); var stepFunc = function() { scrollContainer.scrollTop = Math.min(targetY, pixelsPerStep + scrollContainer.scrollTop); if (scrollContainer.scrollTop >= targetY) { return; } window.requestAnimationFrame(stepFunc); }; window.requestAnimationFrame(stepFunc); }
fuente
scrollContainer = scrollContainer.parentNode
, scrollContainer es nulo. Esto probablemente signifique que no está pasando lo correctoelementId
al llamar a esta función. También es posible que esté ejecutando este script en una página donde ese elementId no existe.elementId
hubiera estado equivocado, habría recibido el mismo error en el caso del ejemplo de @nico, pero en ese caso, el desplazamiento funciona, pero no sin problemas.requestAnimationFrame
lugar desetTimeout
es el camino a seguir.setTimeout
no debe usarse para animaciones.¿Qué pasa si usas la función scrollIntoView?
var elmntToView = document.getElementById("sectionId"); elmntToView.scrollIntoView();
Tiene {comportamiento: "suave"} también ....;) https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
fuente
Tomé la versión de Ned Rockson y la ajusté para permitir desplazamientos hacia arriba también.
var smoothScroll = function(elementId) { var MIN_PIXELS_PER_STEP = 16; var MAX_SCROLL_STEPS = 30; var target = document.getElementById(elementId); var scrollContainer = target; do { scrollContainer = scrollContainer.parentNode; if (!scrollContainer) return; scrollContainer.scrollTop += 1; } while (scrollContainer.scrollTop === 0); var targetY = 0; do { if (target === scrollContainer) break; targetY += target.offsetTop; } while (target = target.offsetParent); var pixelsPerStep = Math.max(MIN_PIXELS_PER_STEP, Math.abs(targetY - scrollContainer.scrollTop) / MAX_SCROLL_STEPS); var isUp = targetY < scrollContainer.scrollTop; var stepFunc = function() { if (isUp) { scrollContainer.scrollTop = Math.max(targetY, scrollContainer.scrollTop - pixelsPerStep); if (scrollContainer.scrollTop <= targetY) { return; } } else { scrollContainer.scrollTop = Math.min(targetY, scrollContainer.scrollTop + pixelsPerStep); if (scrollContainer.scrollTop >= targetY) { return; } } window.requestAnimationFrame(stepFunc); }; window.requestAnimationFrame(stepFunc); };
fuente
Puede usar CSS básico para lograr un desplazamiento suave
fuente
Ned Rockson básicamente responde a esta pregunta. Sin embargo, hay un defecto fatal en su solución. Cuando el elemento de destino está más cerca de la parte inferior de la página que la altura de la ventana gráfica, la función no alcanza su declaración de salida y atrapa al usuario en la parte inferior de la página. Esto se resuelve simplemente limitando el recuento de iteraciones.
var smoothScroll = function(elementId) { var MIN_PIXELS_PER_STEP = 16; var MAX_SCROLL_STEPS = 30; var target = document.getElementById(elementId); var scrollContainer = target; do { scrollContainer = scrollContainer.parentNode; if (!scrollContainer) return; scrollContainer.scrollTop += 1; } while (scrollContainer.scrollTop == 0); var targetY = 0; do { if (target == scrollContainer) break; targetY += target.offsetTop; } while (target = target.offsetParent); var pixelsPerStep = Math.max(MIN_PIXELS_PER_STEP, (targetY - scrollContainer.scrollTop) / MAX_SCROLL_STEPS); var iterations = 0; var stepFunc = function() { if(iterations > MAX_SCROLL_STEPS){ return; } scrollContainer.scrollTop = Math.min(targetY, pixelsPerStep + scrollContainer.scrollTop); if (scrollContainer.scrollTop >= targetY) { return; } window.requestAnimationFrame(stepFunc); }; window.requestAnimationFrame(stepFunc); }
fuente