2009-11-12 19 views
6

Hola chicos, estoy ejecutando jQuery Cycle para una galería de imágenes. Ver el enlace: HereJquery Cycle + Firefox Squishing Images

Mi problema es que las imágenes están siendo aplastadas cuando se ven en firefox. El problema desaparece cuando vuelvo a cargar la página. Esto me lleva a creer que el Javascript se activa antes de que se carguen todas las imágenes (generalmente la primera imagen funciona bien y el resto son aplastadas).

Una re-actualización difícil reproduce el problema.

He envuelto todo en un $ (documento). Listo (función() {}); pero aún sucede.

Información adicional: Si especifico el ancho y alto de la imagen, todo funciona bien. Sin embargo, hay cientos de imágenes, todas en diferentes tamaños.

Estoy bastante frustrado con este problema. ¡Cualquier idea/ayuda es muy apreciada!

Aquí está mi código:

$(document).ready(function(){ 
//function onBefore(curr,next,opts) { 
// var $slide = jQuery(next); 
// var w = $slide.outerWidth(); 
// var h = $slide.outerHeight(); 
// $slide.css({ 
//  marginTop: (482 - h)/2, 
//  marginLeft: (560 - w)/2 
// }); 
//}; 

// Decare the function that center the images... 
function onBefore(curr,next,opts) { 
    var $slide = jQuery(next); 
    var w = $slide.outerWidth(); 
    var h = $slide.outerHeight(); 
    $slide.css({ 
     marginTop: (480 - h)/2, 
     marginLeft: (560 - w)/2 
    }); 
}; 


$(document).ready(function() { 
    $('#slideshow').cycle({ 
    fx:  'fade', 
    next: '#next', 
    pause: 0, 
    speed: 500, 
    before: onBefore, 
    prev: '#prev', 
    pause: '#pause', 
    pager: '.thumbs', 
    pagerClick:function(zeroBasedSlideIndex, slideElement) {$(slideElement).find('div.cover').hide();}, 
    pagerAnchorBuilder: function(idx, slide) { 
         var src = $('img',slide).attr('src'); 
         //Change height of thumbnail here 
         return '<li><a href="#"><img src="' + slide.src + '" height="90" /></a></li>'; 

       } 
    });});}); 

Respuesta

4

que tenían el mismo problema cuando se trabaja en un sitio hace varios meses (enlace más abajo). Si está iniciando un ciclo en $(document).ready(), esto es lo que sucede cuando un cliente navega por su página:

1) El navegador del cliente envía una solicitud para cada elemento img. Esas solicitudes toman cantidades variables de tiempo para cumplir.

2) Antes de completar las solicitudes de imagen, se inicia el ciclo. El ciclo funciona ocultando todas menos la primera imagen en la presentación de diapositivas: establece visibility:hidden y display:none en cada una de sus imágenes.

El problema es que Firefox corrige el tamaño del elemento img de una vez por todas en el punto en que el estilo de visualización está establecido en ninguno. Entonces, si la imagen no ha terminado de cargarse, sus atributos de estilo de alto y ancho son pequeños (no estoy seguro exactamente a qué corresponden, tal vez el tamaño del marcador de posición de la imagen de Firefox). Cuando el ciclo muestra la imagen configurando su atributo de estilo en display:block, usa las dimensiones que tenía en el momento en que estaba oculta.

Lo resolví cambiando mi código para que no inicie el ciclo de compleción hasta que todas las imágenes hayan terminado de cargarse. Para hacer eso, inicializar una variable de contador para el número de imágenes que estoy en bicicleta, a continuación, unirse a un evento de carga a cada imagen como esta:

var imagesRemaining = 12; // 12 is just the number of images in the slideshow div 

$(document).ready(function() { 
    $('#slideshow > img').bind('load', function(e) { 
     imagesRemaining = imagesRemaining - 1; 
     if (imagesRemaining == 0) { 
      // I'm doing some other stuff when initializing cycle 
      startCycle(); 
      // My images all start with visibility:hidden so they don't show 
      // before cycle hides them in a 'stack', so ... 
      $('#slideshow > img').css('visibility', 'visible'); 
     } 
    }); 
}); 

function onBefore(curr, next, opts) { // Your code here ... } 

function startCycle() { 
    $('#slideshow').cycle({ ... // your initialization here }); 
} 

Usted puede verlo en acción mediante la visualización de las galerías de this site en Firefox. Estoy construyendo las páginas de la galería de forma dinámica, por lo que está estructurado de forma un poco diferente que su página, pero puede ver más detalles si explora con Firebug.

+0

Soy algo nuevo en Jquery, ¿cómo implementaría esto? – user184106

+1

He actualizado el ejemplo para mostrarlo un poco más claro. –

2

También me gustaría añadir que parece que agregar un atributo de ancho y alto resuelve este problema.

0

Si está utilizando una base de datos para rellenar la presentación de diapositivas, puede intentar acceder a las dimensiones de la imagen desde la propia imagen.

Por ejemplo, el uso de Django puede utilizar

width="{{ xxx.image.width }}px" height="{{ xxx.image.height }}px" 

en su etiqueta img.

1

Ok sé que es probablemente una forma terrible de llamar a la carga pero yo sólo coulnd ato mi código de ciclo para .load por alguna razón, simplemente no funcionan, así que llamé a todo el inicializador dentro del Ciclo ...

no podría obligar a los tamaños ya que estoy ciclismo a través de Li que contienen imágenes dinámicas y datos

su probablemente defectuosa en cierta medida, pero para aquellos que como yo ... desperated

0

Josh, su solución tiene solo me salvó un dolor de cabeza, muchas gracias!

Creo que lo he modificado ligeramente para poder manejar páginas en las que no se conoce el número total de imágenes. Parece que está funcionando bien para mí, si alguien puede ver algún defecto, por favor indíquelo, todavía estoy aprendiendo.

$(document).ready(function() { 
    $('#slideshow > img').each(
     function go() { 
      $(this).bind('load', function (e) { 
       projects(); 
       $('#slideshow > img').css('visibility', 'visible'); 
      }); 
     }); 
    }); 

function projects() { 
    $('#slideshow').cycle({ 
     fx: 'scrollHorz', 
     speed: 300, 
     timeout: 0, 
     next: '#next ', 
     prev: '#prev ', 
     after: onAfter, 
     nowrap: 1, 
     autostop: 1 
    }); 
} 
12

Hay una solución mucho más simple y más limpio que he utilizado para resolver este problema de lo que ya se ha propuesto:

Usando jQuery, es necesario utilizar $(window).load en lugar de $(document).ready para su situación particular. Para solucionar el problema, cambie esto:

$(document).ready(function() { 
    $('#slideshow').cycle({ 
    /* ... */ 
    }); 
}); 

a esto:

$(window).load(function() { 
    $('#slideshow').cycle({ 
    /* ... */ 
    }); 
}); 

Por qué funciona esto? Porque window.onload se desencadena después de cargar todas las imágenes a las que se hace referencia en la página (consulte https://developer.mozilla.org/en/DOM/window.onload y .load() - jQuery API), que es el comportamiento deseado en su situación. $(document).ready, más conocido como "DOM Ready", se activará antes de que se carguen las imágenes. Este suele ser el comportamiento deseado, pero en su situación es demasiado temprano.

0

Puede usar una solución similar a la de hacer que los videos de youtube respondan. Necesitas saber la proporción entre tu ancho y alto, y agregar eso como relleno al divisor de ciclismo. Para mis fotos 1024x680, solía 680/1024 = 66,4%

En su caso, creo

#slideshow{ padding-bottom:66.4%; } mostrará la imagen no encogido. No tengo idea de con qué valores de alto y ancho real estás trabajando, así que sustituye el tuyo. Tuve que usar esta solución cuando la solución $ (window) .load resultó ser enloquecedoramente ineficaz, así que ahora uso ambas.

Esto es mejor que establecer las dimensiones de la imagen, porque se desliza en un entorno fluido y receptivo.