viernes, 25 de octubre de 2013

¿Por qué mi página al cargar se desplaza hacia abajo? Thanks Google Forms


Le puede pasar a cualquiera, te curras tu nueva entrada al blog y cuando ves cómo queda resulta que ésa página al cargar no se queda quieta sino que de repente de desplaza hacia abajo y te muestra texto que antes quedaba fuera de la ventana. Por supuesto que la cabecera desaparece arrastrada por el scroll vertical.



No sé si es algo que sucede poco o no tuve mucho éxito buscando soluciones a ese problema inesperado. Me pareció tan infrecuente que hasta la única página que me dió la pista definitiva la he perdido en medio del historial del navegador de ayer.

Yo pude verlo en directo con IE 8, aunque haciendo pruebas en Browsershots descubrí que también sucedía (al menos con mi página) en firefox 1.5 (alguien lo usa aún?) y IE 10 e IE 11. Aunque tampoco hay garantías de que no pueda ocurrir con cualquier otro navegador.

Al par de respuestas que encontré, una sugería que se debía al mal soporte de IE a alguna característica CSS (así, sin más y búscate la vida...). Pero si la hoja de estilos valida OK ya me dirás por dónde empiezo.

La otra respuesta, que me hizo ver la luz, comentaba que podía ser debido al atributo autofocus de los campos del formulario. ¡Bingo! Ciertamente, la página se desplazaba hasta mostrar el primer campo del formulario donde parpadeaba el cursor.

En mi caso se trata de un formulario de Google Forms insertado mediante un iframe. Por lo que aunque tuviera el atributo autofocus no podría modificarlo. Si el primer campo del formulario está lo suficientemente arriba para que al cargar la página se muestre sin tener que hacer scroll ni te enterarás, pero si queda más abajo el código javascript (no usa autofocus) que se encarga de llevar el cursos al primer campo provocarà que la página se desplace.

Qué posibles soluciones se me ocurren:

1- Desplazar el formulario hacia arriba en el diseño de la página.

Puede funcionar aunque no entraba en mi diseño.

2- No cargar el iframe hasta que el visitante no de desplace hasta el formulario.

¡Qué remedio! Prové dos formas un pelín distintas de aproximarme a la solución. En los ejemplos uso jQuery.

Cuando el visitante se aproxime generar el código del iframe mediante javascript (tags incluídos). Para hacerlo más genérico se podría poner el src dentro de un span invisible o algo por el estilo en el punto donde desea que aparezca el iframe. De ninguna forma está reflejado en mi ejemplo, estaba cansado y quería algo que me solucionase la papeleta.

var iframeLoaded = 0;   // Variable usada para no cargar varias veces el mismo iframe;

$( document ).ready(function() {
  $(window).scroll(function(){
      /* Cuando la altura de la ventana más la posición actual
         (con eso obtengo la posición que se ocupa en la parte baja del display,
         es mayor o igual a la posición que ocupa el elemento en cuestión será cuando se muestre el formulario.
         Además, si el formulario ya se ha cargado no se repite la operación. */
    if ($(this).height() + $(this).scrollTop() >= $('#contacta').offset().top && iframeLoaded == 0) {
      $('<iframe />', {
        name: 'formulario',
        id: 'formulario',
        frameborder: '0',
        src: 'https://docs.google.com/forms/d/1uH9FKShFpf1XIVdbrh7xH68vCkbyHe07MF6ZO5uuVJI/viewform?embedded=true'
      }).appendTo('#contacta');

      iframeLoaded = 1;
    }
  });
});

#contacta hace referencia a un div que debía contener el iframe.

El otro punto de vista. Dejar el iframe donde estaba pero no mostrarlo display:none y hacer que se muestre en su momento.

$( document ).ready(function() {
  $(window).scroll(function(){
    if ($(this).height() + $(this).scrollTop() >= $('#contacta').offset().top && iframeLoaded == 0) {
      $('#formulario').css( "display", "block" );
    }
  });
});

#formulario hace referencia al iframe. Éste último es más sencillo aunque salta un error en la consola del navegador debido a que "no se le puede dar el foco a un elemento que no está visible". De todas formas funciona, así que me decanté por éste útlimo método.

¿Se os ocurre alguna otra forma de afrontarlo?

No hay comentarios:

Publicar un comentario