javascript - controlar - window scrollto slow
jQuery scrollTop() no parece funcionar en Safari o Chrome(Windows) (19)
Tengo una configuración simple para permitir que una ventana de estilo de "ayuda" sea cargada y desplazada a un punto particular en la página. Más o menos el código se ve así:
var target = /* code */;
target.offsetParent().scrollTop(target.offset().top - fudgeValue);
El objetivo del desplazamiento y el valor de fudge están determinados por un par de pistas que se dejan caer en la página, y no tengo problemas con esa parte de este mecanismo en ninguna parte. En Firefox e IE8, el código anterior funciona exactamente como yo quiero: el cuadro desplazado (en este caso, el cuerpo de la página) desplaza correctamente las cosas contenidas al punto correcto de la ventana cuando se le indica que lo haga.
En Chrome y Safari, sin embargo, la llamada a scrollTop () aparentemente no hace nada. Todos los números están bien, y el objetivo se refiere a lo correcto (y el offsetParent () es de hecho el elemento de cuerpo), pero no sucede nada en absoluto. Por lo que puedo decir al buscar en Google, se supone que esto funciona. ¿Hay algo divertido sobre el renderizador en Safari y Chrome?
Esto es jQuery 1.3.2 si eso es importante.
Página de prueba: http://gutfullofbeer.net/scrolltop.html
¿Qué elemento es el offsetParent
de otro no está bien especificado y puede variar entre los navegadores. No se garantiza que sea el padre desplazable que está buscando.
El cuerpo en sí mismo tampoco debería ser el principal elemento desplazable de la página. Solo está en el modo Quirks, que en general querrías evitar.
Las offsetTop
/ offsetLeft
/ offsetParent
no son terriblemente útiles por sí mismas, solo son realmente confiables cuando las usa en un ciclo para obtener el total de coordenadas relativas a la página (como position()
en jQuery ) Debería saber cuál es el elemento que desea desplazarse y descubrir la diferencia en las coordenadas de página entre ese y el target
descendiente para averiguar cuánto desplazarse por él.
O si siempre está la página en sí, está hablando de desplazamiento, simplemente use una navegación location.href= ''#''+target.id
lugar.
De hecho, parece que se necesita animación para que funcione en Safari. Terminé con:
if($.browser.safari)
bodyelem = $("body");
else
bodyelem = $("html,body");
bodyelem.animate({scrollTop:0},{queue:false, duration:100, easing:"linear", complete:callbackFunc});
El estado de soporte del navegador es este:
IE8, Firefox, Opera: $("html")
Chrome, Safari: $("body")
Entonces esto funciona:
bodyelem = $.browser.safari ? $("body") : $("html") ;
bodyelem.animate( {scrollTop: 0}, 500 );
En mi caso, el botón funcionaba para dos de los 8 enlaces. Mi solución fue
$("body,html,document").animate({scrollTop:$("#myLocation").offset().top},2500);
Esto creó un bonito efecto de desplazamiento también
Estaba enfrentando este problema, creé este enlace en la parte inferior e implementé el código jQuery scrollTop y funcionó perfectamente en Firefox, IE, Opera pero no funcionó en Chrome y Safari. Estoy aprendiendo jQuery, así que no sé si esta solución es técnicamente perfecta, pero esto funcionó para mí. Acabo de implementar 2 códigos ScrollTop, el primero usa $ (''html'') que funciona para Firefox, etc. El segundo usa $ (''cuerpo html'') esto funciona para Chrome y Safari.
$(''a#top'').click(function() {
$(''html'').animate({scrollTop: 0}, ''slow'');
return false;
$(''html body'').animate({scrollTop: 0}, ''slow'');
return false;
});
Estaba teniendo este problema en Safari y Chrome (Mac) y descubrí que .scrollTop
funcionaría en $("body")
pero no $("html, body")
, FF e IE, pero funciona al revés. Un simple navegador de detección corrige el problema:
if($.browser.safari)
bodyelem = $("body")
else
bodyelem = $("html,body")
bodyelem.scrollTop(100)
El valor del navegador jQuery para Chrome es Safari, por lo que solo tiene que hacer una detección al respecto.
Espero que esto ayude a alguien.
Esto parece estar funcionando en FF y WebKit; IE no probado hasta el momento.
$(document).scrollTop();
Funciona para Safari, Firefox e IE7 (no han probado IE8). Prueba simple:
<button onclick=''$("body,html").scrollTop(0);''> Top </button>
<button onclick=''$("body,html").scrollTop(100);''> Middle </button>
<button onclick=''$("body,html").scrollTop(250);''> Bottom </button>
La mayoría de los ejemplos usan uno o ambos, pero en orden inverso (es decir, "html, cuerpo").
Aclamaciones.
(Y los puristas semánticos por ahí, no se desanimen: he estado buscando esto durante semanas, este es un ejemplo simple , que valida XHTML estricto. Siéntase libre de crear 27 capas de abstracción y de hinchamiento de eventos para su OCD Tranquilidad: solo por favor denle el debido crédito, ya que las personas en los foros de jQuery, SO, y G no pudieron sacar los productos.
Hay un error en Chrome (no en Safari en el momento en que lo verificamos) que da resultados inesperados en varias medidas de ancho y alto de Javascript al abrir pestañas en el fondo ( detalles del error aquí ) - registramos el error en junio y no ha sido resuelto desde .
Es posible que hayas encontrado el error en lo que intentas hacer.
Me funcionó, solo déjalo en jQuery.
$("html,body").animate({ scrollTop: 0 }, 1);
Básicamente, debe conocer el navegador y escribir el código teniendo en cuenta las diferencias del navegador. Como jQuery es un navegador cruzado, debe manejar el primer paso. Y finalmente falsificas el motor js del navegador animando el desplazamiento en 1 milisegundo.
No es realmente un error, solo una diferencia en la implantación por parte de los proveedores de navegadores.
Como regla, evite olfatear el navegador. Hay una solución jQuery ingeniosa que se insinúa en las respuestas.
Esto es lo que funciona para mí: $(''html:not(:animated),body:not(:animated)'').scrollTop()
No estoy seguro si este es el caso:
Estaba usando el CDN de Google para jQuery, es decir,
Poniendo "https:"
antes de que //ajax.google.......
funcionara, parece que Safari lo reconoció como una ruta local (verificada por - Inspeccionar Elemento)
Lo siento, solo probado en Safari 7.0.3 :(
No hay una gran variedad de elementos que puedan asignarse automáticamente con un valor de scrollTop a medida que desplazamos una página web.
Así que escribí esta pequeña función para recorrer los elementos probables y devolver el que buscamos.
var grab=function (){
var el=$();
$(''body#my_body, html, document'').each(function(){
if ($(this).scrollTop()>0) {
el= ($(this));
return false;
}
})
return el;
}
//alert(grab().scrollTop());
En Google Chrome obtendríamos el cuerpo, en IE - HTML.
(Tenga en cuenta que no es necesario establecer el overflow:auto
explícitamente en nuestro html o cuerpo de esa manera).
Para el scroll: ''html'' o ''body'' para setter (depende del navegador) ... ''window'' para getter ...
Un jsFiddle para pruebas está aquí: http://jsfiddle.net/molokoloco/uCrLa/
var $window = $(window), // Set in cache, intensive use !
$document = $(document),
$body = $(''body''),
scrollElement = ''html, body'',
$scrollElement = $();
var isAnimated = false;
// Find scrollElement
// Inspired by http://www.zachstronaut.com/posts/2009/01/18/jquery-smooth-scroll-bugs.html
$(scrollElement).each(function(i) {
// ''html, body'' for setter... window for getter...
var initScrollTop = parseInt($(this).scrollTop(), 10);
$(this).scrollTop(initScrollTop + 1);
if ($window.scrollTop() == initScrollTop + 1) {
scrollElement = this.nodeName.toLowerCase(); // html OR body
return false; // Break
}
});
$scrollElement = $(scrollElement);
// UTILITIES...
var getHash = function() {
return window.location.hash || '''';
},
setHash = function(hash) {
if (hash && getHash() != hash) window.location.hash = hash;
},
getWinWidth = function() {
return $window.width();
},
// iphone ? ((window.innerWidth && window.innerWidth > 0) ? window.innerWidth : $window.width());
getWinHeight = function() {
return $window.height();
},
// iphone ? ((window.innerHeight && window.innerHeight > 0) ? window.innerHeight : $window.height());
getPageWidth = function() {
return $document.width();
},
getPageHeight = function() {
return $document.height();
},
getScrollTop = function() {
return parseInt($scrollElement.scrollTop() || $window.scrollTop(), 10);
},
setScrollTop = function(y) {
$scrollElement.stop(true, false).scrollTop(y);
},
myScrollTo = function(y, newAnchror) { // Call page scrolling to a value (like native window.scrollBy(x, y)) // Can be flooded
isAnimated = true; // kill waypoint AUTO hash
var duration = 360 + (Math.abs(y - getScrollTop()) * 0.42); // Duration depend on distance...
if (duration > 2222) duration = 0; // Instant go !! ^^
$scrollElement.stop(true, false).animate({
scrollTop: y
}, {
duration: duration,
complete: function() { // Listenner of scroll finish...
if (newAnchror) setHash(newAnchror); // If new anchor
isAnimated = false;
}
});
},
goToScreen = function(dir) { // Scroll viewport page by paginette // 1, -1 or factor
var winH = parseInt((getWinHeight() * 0.75) * dir); // 75% de la hauteur visible comme unite
myScrollTo(getScrollTop() + winH);
};
myScrollTo((getPageHeight() / 2), ''iamAMiddleAnchor'');
Para resumir las soluciones de un par de preguntas / respuestas:
Si desea obtener el desplazamiento de desplazamiento actual, use:
$(document).scrollTop()
Para configurar el desplazamiento de desplazamiento use:
$(''html,body'').scrollTop(x)
Para animar el uso de desplazamiento, use:
$(''html,body'').animate({scrollTop: x});
Sí, parece que hay un error en Chrome cuando se trata de modificar el body
, tratando de convertirlo en offsetParent
. Como #content
, le sugiero que simplemente agregue otro div para envolver el #content
div, y #content
ese desplazamiento:
html, body { height: 100%; padding: 0; }
html { width: 100%; background-color: #222; overflow: hidden; margin: 0; }
body
{
width: 40em; margin: 0px auto; /* narrow center column layout */
background-color: white;
position: relative; /* allow positioning children relative to this element */
}
#scrollContainer /* wraps #content, scrolls */
{
overflow: auto; /* scroll! */
position:absolute; /* make offsetParent */
top: 0; height: 100%; width: 100%; /* fill parent */
}
#header
{
position: absolute;
top: 0px; height: 50px; width: 38.5em;
background-color: white;
z-index: 1; /* sit above #content in final layout */
}
#content { padding: 5px 14px 50px 5px; }
Probado en FF 3.5.5, Chrome 3.0.195.33, IE8
Demostración en vivo:
$(function() {
$(''#header'').find(''button'').click(function(ev) {
var button = $(this), target = $(''div.'' + button.attr(''class''));
var scroll = target.offsetParent().scrollTop();
target.offsetParent().scrollTop(target.offset().top + scroll - 50);
});
});
html, body { height: 100%; padding: 0; }
html { width: 100%; background-color: #222; overflow: hidden; margin: 0; }
body { width: 40em; margin: 0px auto; background-color: white; position: relative; }
#scrollContainer { overflow: auto; position:absolute; top: 0; height: 100%; width: 100%; }
#header { position: absolute; top: 0px; height: 50px; width: 38.5em; background-color: white; z-index: 1; }
#content { padding: 5px 14px 50px 5px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id=''header''>
Header Box
<button class=''A''>A</button>
<button class=''B''>B</button>
<button class=''C''>C</button>
</div>
<div id=''scrollContainer''>
<div id=''content''>
<div style=''height: 50px''> </div>
<div class=''A''>
<h1>A</h1>
<p>My name is Boffer Bings. I was born of honest parents in one of the humbler walks of life, my father being a manufacturer of dog-oil and my mother having a small studio in the shadow of the village church, where she disposed of unwelcome babes. In my boyhood I was trained to habits of industry; I not only assisted my father in procuring dogs for his vats, but was frequently employed by my mother to carry away the debris of her work in the studio. In performance of this duty I sometimes had need of all my natural intelligence for all the law officers of the vicinity were opposed to my mother''s business. They were not elected on an opposition ticket, and the matter had never been made a political issue; it just happened so. My father''s business of making dog-oil was, naturally, less unpopular, though the owners of missing dogs sometimes regarded him with suspicion, which was reflected, to some extent, upon me. My father had, as silent partners, all the physicians of the town, who seldom wrote a prescription which did not contain what they were pleased to designate as _Ol. can._ It is really the most valuable medicine ever discovered. But most persons are unwilling to make personal sacrifices for the afflicted, and it was evident that many of the fattest dogs in town had been forbidden to play with me--a fact which pained my young sensibilities, and at one time came near driving me to become a pirate.
</div>
<div class=''B''>
<h1>B</h1>
<p>
Looking back upon those days, I cannot but regret, at times, that by indirectly bringing my beloved parents to their death I was the author of misfortunes profoundly affecting my future.
<p>
One evening while passing my father''s oil factory with the body of a foundling from my mother''s studio I saw a constable who seemed to be closely watching my movements. Young as I was, I had learned that a constable''s acts, of whatever apparent character, are prompted by the most reprehensible motives, and I avoided him by dodging into the oilery by a side door which happened to stand ajar. I locked it at once and was alone with my dead. My father had retired for the night. The only light in the place came from the furnace, which glowed a deep, rich crimson under one of the vats, casting ruddy reflections on the walls. Within the cauldron the oil still rolled in indolent ebullition, occasionally pushing to the surface a piece of dog. Seating myself to wait for the constable to go away, I held the naked body of the foundling in my lap and tenderly stroked its short, silken hair. Ah, how beautiful it was! Even at that early age I was passionately fond of children, and as I looked upon this cherub I could almost find it in my heart to wish that the small, red wound upon its breast--the work of my dear mother--had not been mortal.
</div>
<div class=''C''>
<h1>C</h1>
<p>It had been my custom to throw the babes into the river which nature had thoughtfully provided for the purpose, but that night I did not dare to leave the oilery for fear of the constable. "After all," I said to myself, "it cannot greatly matter if I put it into this cauldron. My father will never know the bones from those of a puppy, and the few deaths which may result from administering another kind of oil for the incomparable _ol. can._ are not important in a population which increases so rapidly." In short, I took the first step in crime and brought myself untold sorrow by casting the babe into the cauldron.
</div>
<div style=''height: 75em;''> </div>
</div>
</div>
qué tal si
var top = $(''html'').scrollTop() || $(''body'').scrollTop();
$("body,html,document").scrollTop($("#map_canvas").position().top);
Esto funciona para Chrome 7, IE6, IE7, IE8, IE9, FF 3.6 y Safari 5.
ACTUALIZACIÓN 2012
Esto sigue siendo bueno, pero tuve que usarlo de nuevo. A veces, la position
no funciona, por lo que esta es una alternativa:
$("body,html,document").scrollTop($("#map_canvas").offset().top);
setTimeout(function() {
$("body,html,document").scrollTop( $(''body'').height() );
}, 100);
Esto probablemente debería funcionar incluso si el tiempo es de 10 ms.