iconos glyphicon example bootstrap jquery firefox scrolltop

jquery - glyphicon - Animate scrollTop no funciona en Firefox



icons bootstrap 4 (10)

Esta función funciona bien. Desplaza el cuerpo al desplazamiento de un contenedor deseado

function scrolear(destino){ var stop = $(destino).offset().top; var delay = 1000; $(''body'').animate({scrollTop: stop}, delay); return false; }

Pero no en Firefox. ¿Por qué?

-EDITAR-

Para manejar el doble disparador en la respuesta aceptada, sugiero que se detenga el elemento antes de la animación:

$(''body,html'').stop(true,true).animate({scrollTop: stop}, delay);


Cuidado con esto Tuve el mismo problema, ni Firefox ni Explorer desplazándose con

$(''body'').animate({scrollTop:pos_},1500,function(){do X});

Así que usé como David dijo

$(''body, html'').animate({scrollTop:pos_},1500,function(){do X});

Funcionó bien, pero un nuevo problema, ya que hay dos elementos, cuerpo y html, la función se ejecuta dos veces, esto es, do X se ejecuta dos veces.

intenté solo con ''html'', y Firefox y Explorer funcionan, pero ahora Chrome no es compatible con esto.

Necesito cuerpo para Chrome y html para Firefox y Explorer. ¿Es un error jQuery? no lo sé

Solo ten cuidado con tu función, ya que funcionará dos veces.


Es posible que desee evitar el problema mediante el uso de un complemento, más específicamente, mi complemento :)

En serio, aunque hace tiempo que se ha abordado el problema básico (los diferentes navegadores utilizan diferentes elementos para el desplazamiento de las ventanas), hay bastantes cuestiones no triviales que pueden hacer que te pases por alto:

  • Simplemente animando tanto body como html tiene sus problemas ,
  • la comprobación de características del comportamiento real del navegador es complicado de corregir (ver mis comentarios en la respuesta de Stephen @ ),
  • pero lo más importante es que hay un montón de problemas de usabilidad con los que te gustaría lidiar para tener una experiencia de usuario decente.

Obviamente, soy parcial, pero jQuery.scrollable es en realidad una buena opción para abordar estos problemas. (De hecho, no conozco ningún otro complemento que maneje todos).

Además, puede calcular la posición objetivo, aquella a la que se desplaza, de forma a prueba de balas con la función getScrollTargetPosition() en este sentido .

Todo lo cual te dejaría con

function scrolear ( destino ) { var $window = $( window ), targetPosition = getScrollTargetPosition ( $( destino ), $window ); $window.scrollTo( targetPosition, { duration: 1000 } ); return false; }


Este es el verdadero negocio. Funciona sin problemas en Chrome y Firefox. Incluso es triste que algunos ignorantes me voten. Este código funciona literalmente perfectamente como en todos los navegadores. Solo necesita agregar un enlace y colocar el ID del elemento que desea desplazar en el href y funciona sin especificar nada. Código puro reutilizable y confiable.

$(document).ready(function() { function filterPath(string) { return string .replace(/^///,'''') .replace(/(index|default).[a-zA-Z]{3,4}$/,'''') .replace(///$/,''''); } var locationPath = filterPath(location.pathname); var scrollElem = scrollableElement(''html'', ''body''); $(''a[href*=#]'').each(function() { var thisPath = filterPath(this.pathname) || locationPath; if (locationPath == thisPath && (location.hostname == this.hostname || !this.hostname) && this.hash.replace(/#/,'''') ) { var $target = $(this.hash), target = this.hash; if (target) { var targetOffset = $target.offset().top; $(this).click(function(event) { event.preventDefault(); $(scrollElem).animate({scrollTop: targetOffset}, 400, function() { location.hash = target; }); }); } } }); // use the first element that is "scrollable" function scrollableElement(els) { for (var i = 0, argLength = arguments.length; i <argLength; i++) { var el = arguments[i], $scrollElement = $(el); if ($scrollElement.scrollTop()> 0) { return el; } else { $scrollElement.scrollTop(1); var isScrollable = $scrollElement.scrollTop()> 0; $scrollElement.scrollTop(0); if (isScrollable) { return el; } } } return []; } });


Firefox coloca el desbordamiento en el nivel html , a menos que tenga un estilo específico para comportarse de manera diferente.

Para que funcione en Firefox, usa

$(''body,html'').animate( ... );

Ejemplo de trabajo

La solución CSS sería establecer los siguientes estilos:

html { overflow: hidden; height: 100%; } body { overflow: auto; height: 100%; }

Supongo que la solución JS sería menos invasiva.

Actualizar

Gran parte de la discusión a continuación se centra en el hecho de que la animación de scrollTop de dos elementos provocaría que la devolución de llamada se invocara dos veces. Las funciones de detección del navegador se han sugerido y posteriormente se han desaprobado, y algunas son bastante descabelladas.

Si la devolución de llamada es idempotente y no requiere mucha potencia informática, dispararla dos veces puede ser un completo no problema. Si las invocaciones múltiples de la devolución de llamada son realmente un problema, y ​​si desea evitar la detección de características, podría ser más directo exigir que la devolución de llamada solo se ejecute una vez desde la devolución de llamada:

function runOnce(fn) { var count = 0; return function() { if(++count == 1) fn.apply(this, arguments); }; }; $(''body, html'').animate({ scrollTop: stop }, delay, runOnce(function() { console.log(''scroll complete''); }));


La detección de funciones y luego la animación en un único objeto compatible sería bueno, pero no hay una solución de una sola línea. Mientras tanto, esta es una forma de utilizar la promesa de hacer una única devolución de llamada por ejecución.

$(''html, body'') .animate({ scrollTop: 100 }) .promise() .then(function(){ // callback code here }) });

ACTUALIZAR: Así es como podría usar la detección de características en su lugar. Este trozo de código necesita ser evaluado antes de su llamada de animación:

// Note that the DOM needs to be loaded first, // or else document.body will be undefined function getScrollTopElement() { // if missing doctype (quirks mode) then will always use ''body'' if ( document.compatMode !== ''CSS1Compat'' ) return ''body''; // if there''s a doctype (and your page should) // most browsers will support the scrollTop property on EITHER html OR body // we''ll have to do a quick test to detect which one... var html = document.documentElement; var body = document.body; // get our starting position. // pageYOffset works for all browsers except IE8 and below var startingY = window.pageYOffset || body.scrollTop || html.scrollTop; // scroll the window down by 1px (scrollTo works in all browsers) var newY = startingY + 1; window.scrollTo(0, newY); // And check which property changed // FF and IE use only html. Safari uses only body. // Chrome has values for both, but says // body.scrollTop is deprecated when in Strict mode., // so let''s check for html first. var element = ( html.scrollTop === newY ) ? ''html'' : ''body''; // now reset back to the starting position window.scrollTo(0, startingY); return element; } // store the element selector name in a global var - // we''ll use this as the selector for our page scrolling animation. scrollTopElement = getScrollTopElement();

Ahora use la var que acabamos de definir como el selector para la animación de desplazamiento de página, y use la sintaxis regular:

$(scrollTopElement).animate({ scrollTop: 100 }, 500, function() { // normal callback });


Para mí, el problema fue que Firefox saltó automáticamente al ancla con el nombre-atributo igual que el nombre hash que puse en la URL. Aunque puse .preventDefault () para evitar eso. Entonces, después de cambiar los atributos del nombre, Firefox no saltó automáticamente a los anclajes, sino que realizó la animación correcta.

@Toni Lo siento si esto no fue comprensible. El caso es que cambié los valores hash en la URL como www.someurl.com/#hashname. Luego tuve, por ejemplo, un anclaje como <a name="hashname" ...></a> al cual jQuery debería desplazarse automáticamente. Pero no lo hizo porque saltó directamente al ancla con el atributo de nombre correspondiente en Firefox sin ninguna animación de desplazamiento. Una vez que cambié el atributo de nombre a algo diferente del nombre hash, por ejemplo a name="hashname-anchor" , el desplazamiento funcionó.


Para mí, fue evitar agregar la identificación en el momento de la animación:

Evitando:

scrollTop: $(''#'' + id).offset().top

Preparando la identificación de antemano y haciendo esto en su lugar:

scrollTop: $(id).offset().top

Solucionado en FF. (Las adiciones de css no hicieron una diferencia para mí)


Pasé muchas eras tratando de descubrir por qué mi código no funcionaba:

$(''body,html'').animate({scrollTop: 50}, 500);

El problema estaba en mi css -

body { height: 100%};

Lo configuré en auto (y me quedé preocupado acerca de por qué estaba configurado al 100% en primer lugar). Eso lo solucionó para mí.


Yo recomendaría no confiar en body o html como una solución más portátil. Simplemente agregue un div en el cuerpo que pretende contener los elementos desplazados y estilo para habilitar el desplazamiento de tamaño completo:

#my-scroll { position: absolute; width: 100%; height: 100%; overflow: auto; }

(asumiendo que display:block; y top:0;left:0; son valores predeterminados que coincidan con su objetivo), luego use $(''#my-scroll'') para sus animaciones.


setTimeout(function(){ $(''html,body'').animate({ scrollTop: top }, 400); },0);

Espero que esto funcione.