javascript - efecto - Cómo agregar un desplazamiento suave a la función de espionaje de desplazamiento de Bootstrap
scroll js (6)
He intentado agregar una función de desplazamiento suave a mi sitio por un tiempo pero parece que no funciona.
Aquí está mi código HTML relacionado con mi navegación:
<div id="nav-wrapper">
<div id="nav" class="navbar navbar-inverse affix-top" data-spy="affix" data-offset-top="675">
<div class="navbar-inner" data-spy="affix-top">
<div class="container">
<!-- .btn-navbar is used as the toggle for collapsed navbar content -->
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<!-- Everything you want hidden at 940px or less, place within here -->
<div class="nav-collapse collapse">
<ul class="nav">
<li><a href="#home">Home</a></li>
<li><a href="#service-top">Services</a></li>
<li><a href="#contact-arrow">Contact</a></li>
</ul><!--/.nav-->
</div><!--/.nav-collapse collapse pull-right-->
</div><!--/.container-->
</div><!--/.navbar-inner-->
</div><!--/#nav /.navbar navbar-inverse-->
</div><!--/#nav-wrapper-->
Aquí está el código JS que he agregado:
<script src="js/jquery.scrollTo-1.4.3.1-min.js"></script>
<script>
$(document).ready(function(e) {
$(''#nav'').scrollSpy()
$(''#nav ul li a'').bind(''click'', function(e) {
e.preventDefault();
target = this.hash;
console.log(target);
$.scrollTo(target, 1000);
});
});
</script>
Por lo que vale, here es donde recibí información sobre lo que he hecho hasta ahora, y here está mi sitio en su forma actual. Si puedes ayudarme, te hornearé un pastel o galletas o algo así. ¡Gracias!
¿Realmente necesitas ese complemento? Solo puede animar la propiedad scrollTop
:
$("#nav ul li a[href^=''#'']").on(''click'', function(e) {
// prevent default anchor click behavior
e.preventDefault();
// store hash
var hash = this.hash;
// animate
$(''html, body'').animate({
scrollTop: $(hash).offset().top
}, 300, function(){
// when done, add hash to url
// (default click behaviour)
window.location.hash = hash;
});
});
Lo combiné, y este es el resultado -
$(document).ready(function() {
$("#toTop").hide();
// fade in & out
$(window).scroll(function () {
if ($(this).scrollTop() > 400) {
$(''#toTop'').fadeIn();
} else {
$(''#toTop'').fadeOut();
}
});
$(''a[href*=#]'').each(function() {
if (location.pathname.replace(/^///,'''') == this.pathname.replace(/^///,'''')
&& location.hostname == this.hostname
&& this.hash.replace(/#/,'''') ) {
var $targetId = $(this.hash), $targetAnchor = $(''[name='' + this.hash.slice(1) +'']'');
var $target = $targetId.length ? $targetId : $targetAnchor.length ? $targetAnchor : false;
if ($target) {
var targetOffset = $target.offset().top;
$(this).click(function() {
$(''html, body'').animate({scrollTop: targetOffset}, 400);
return false;
});
}
}
});
});
Lo probé y funciona bien. Espero que esto ayude a alguien :)
Lo que onetrickpony
publicó está bien, pero si quieres tener una solución más general, puedes usar el siguiente código.
En lugar de seleccionar solo la id
del delimitador, puede hacerlo un poco más estándar y simplemente seleccionando el name
del atributo de la <a>
-Tag. Esto le ahorrará escribir una etiqueta de id
adicional. Simplemente agregue la clase smoothscroll al elemento barra de navegación.
Qué cambió
1) $(''#nav ul li a[href^="#"]'')
a $(''#nav.smoothscroll ul li a[href^="#"]'')
2) $(this.hash)
a $(''a[name="'' + this.hash.replace(''#'', '''') + ''"]'')
Código final
/* Enable smooth scrolling on all links with anchors */
$(''#nav.smoothscroll ul li a[href^="#"]'').on(''click'', function(e) {
// prevent default anchor click behavior
e.preventDefault();
// store hash
var hash = this.hash;
// animate
$(''html, body'').animate({
scrollTop: $(''a[name="'' + this.hash.replace(''#'', '''') + ''"]'').offset().top
}, 300, function(){
// when done, add hash to url
// (default click behaviour)
window.location.hash = hash;
});
});
Si descargas el plugin jquery easing (compruébalo) , solo tienes que agregarlo a tu archivo main.js:
$(''a.smooth-scroll'').on(''click'', function(event) {
var $anchor = $(this);
$(''html, body'').stop().animate({
scrollTop: $($anchor.attr(''href'')).offset().top + 20
}, 1500, ''easeInOutExpo'');
event.preventDefault();
});
y tampoco te olvides de agregar la clase smooth-scroll a tus etiquetas a como esta:
<li><a href="#about" class="smooth-scroll">About Us</a></li>
Si tienes una barra de navegación fija, necesitarás algo como esto.
Tomando de la mejor de las respuestas y comentarios anteriores ...
$(".bs-js-navbar-scrollspy li a[href^=''#'']").on(''click'', function(event) {
var target = this.hash;
event.preventDefault();
var navOffset = $(''#navbar'').height();
return $(''html, body'').animate({
scrollTop: $(this.hash).offset().top - navOffset
}, 300, function() {
return window.history.pushState(null, null, target);
});
});
En primer lugar, para evitar el error "indefinido", almacene el hash en una variable, target
, antes de llamar a preventDefault()
, y luego haga referencia al valor almacenado en su lugar, como lo menciona pupadupa.
Siguiente. No puede usar window.location.hash = target
porque establece la url y la ubicación de forma simultánea en lugar de por separado. Al final del elemento cuyo ID coincide con el href ... pero que está cubierto por la barra de navegación superior fija, terminará teniendo la ubicación.
Para evitar esto, establezca su valor scrollTop en el valor de ubicación de desplazamiento vertical del objetivo menos la altura de su barra de navegación fija. Dirigirse directamente a ese valor mantiene un desplazamiento suave, en lugar de agregar un ajuste después, y obtener un nerviosismo de aspecto poco profesional.
Notará que la url no cambia. Para configurar esto, use return window.history.pushState(null, null, target);
en su lugar, para agregar manualmente la url a la pila de historial.
¡Hecho!
Otras notas:
1) utilizando el método .on
es el último método de jquery (a partir de enero de 2015) que es mejor que .bind
o .live
, o incluso .click
en los motivos que le dejo para que lo descubra.
2) el valor de navOffset puede estar dentro o fuera de la función, pero es probable que desee que esté fuera, ya que puede muy bien hacer referencia a ese espacio vertical para otras funciones / manipulaciones de DOM. Pero lo dejé dentro para hacerlo claramente en una función.
$("#YOUR-BUTTON").on(''click'', function(e) {
e.preventDefault();
$(''html, body'').animate({
scrollTop: $("#YOUR-TARGET").offset().top
}, 300);
});