2009-11-12 8 views
6

Hé les gars, je cours jQuery Cycle pour une galerie d'images. Afficher le lien: HereJquery Cycle + Firefox Squishing Images

Mon problème est que les images sont écrasées lorsqu'elles sont vues dans Firefox. Le problème disparaît lorsque je recharge la page. Cela m'amène à croire que le Javascript est en train de se déclencher avant que toutes les images soient chargées (habituellement la première image fonctionne bien et les autres sont écrasées.)

Un nouveau disque dur reproduit le problème.

J'ai enveloppé tout dans un $ (document) .ready (function() {}); mais ça arrive encore.

Informations supplémentaires: Si je spécifie la largeur et la hauteur de l'image, tout fonctionne correctement. Cependant il y a des centaines d'images toutes à différentes tailles.

Je suis assez frustré par ce problème. Toute idée/aide est grandement appréciée!

Voici mon code:

$(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>'; 

       } 
    });});}); 

Répondre

4

J'ai eu le même problème lorsque vous travaillez sur un site il y a plusieurs mois (lien ci-dessous). Si vous commencez le cycle dans $(document).ready(), voici ce qui se passe lorsqu'un client accède à votre page:

1) Le navigateur du client envoie une demande pour chaque élément img. Ces demandes prennent des quantités variables de temps à remplir.

2) Avant que les demandes d'images soient terminées, le cycle commence. Cycle fonctionne en masquant toutes les images sauf le premier dans le diaporama: il définit visibility:hidden et display:none sur chacune de ses images.

Le problème est que Firefox fixe la taille de l'élément img une fois pour toutes au moment où le style d'affichage est défini sur. Donc, si l'image n'a pas fini de se charger, ses attributs de style hauteur et largeur sont petits (je ne suis pas sûr exactement ce qu'ils correspondent - peut-être la taille de l'espace réservé d'image de Firefox). Lorsque le cycle montre l'image en définissant son attribut de style à display:block, il utilise toutes les dimensions qu'il avait au moment où il a été caché.

J'ai résolu ceci en changeant mon code de sorte qu'il ne démarre pas le plugin de cycle jusqu'à ce que toutes les images aient fini de se charger. Pour ce faire, j'initialiser une variable compteur au nombre d'images que je suis à vélo, puis liez un événement de charge à chaque image comme ceci:

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 }); 
} 

Vous pouvez le voir en action en regardant les galeries sur this site en Firefox. Je construis les pages de la galerie de manière dynamique, donc c'est structuré un peu différemment de votre page, mais vous pouvez voir plus de détails si vous fouillez avec Firebug.

+0

Je suis un peu nouveau à Jquery, comment pourrais-je implémenter ceci? – user184106

+1

J'ai mis à jour l'exemple pour le montrer un peu plus clairement. –

2

Je voudrais aussi ajouter qu'il semble que l'ajout d'un attribut width et height résout ce problème.

0

Si vous utilisez une base de données pour remplir le diaporama, vous pouvez essayer d'accéder aux dimensions de l'image à partir de l'image elle-même.

Par exemple, en utilisant django vous pouvez utiliser

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

dans votre balise img.

1

Ok je sais qu'il ya probablement un moyen awfull d'appeler la charge mais je coulnd lie mon code de cycle à .load pour une raison quelconque, il ne fonctionne pas tellement j'ai appelé tout le cycle initialiseur à l'intérieur du ...

je ne pouvais pas forcer les tailles depuis que je suis à vélo à travers li contenant des images dynamiques et les données

son viciée probablement à une certaine mesure, mais pour ceux que desperated comme moi ...

0

Josh, votre solution a juste m'a sauvé un mal de tête, merci beaucoup!

Je pense que je l'ai légèrement modifié afin de gérer les pages où vous ne connaissez pas le nombre total d'images. Cela semble fonctionner correctement pour moi, si quelqu'un peut voir des défauts, s'il vous plaît signalez-les - j'apprends encore.

$(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

Il y a une solution beaucoup plus simple et plus propre que je l'habitude de résoudre ce problème que ce qui a déjà été proposé:

En utilisant jQuery, vous devez utiliser $(window).load au lieu de $(document).ready pour votre situation particulière. Pour résoudre le problème, changer ceci:

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

à ceci:

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

Pourquoi ce travail? Parce que window.onload incendies après toutes les images référencées sur la page sont chargés (Voir https://developer.mozilla.org/en/DOM/window.onload, et .load() - jQuery API), qui est le comportement souhaité dans votre situation. $(document).ready, mieux connu sous le nom "DOM Ready", se déclenchera avant que les images ne soient chargées. C'est généralement le comportement souhaité, mais dans votre situation, il est trop tôt.

0

Vous pouvez utiliser une solution similaire à la réactivité des vidéos YouTube. Vous devez connaître le rapport de votre largeur à la hauteur, et l'ajouter comme fond de rembourrage à la division cycliste. Pour mes 1024x680 photos je 680/1024 = 66,4%

Dans votre cas, je crois

#slideshow{ padding-bottom:66.4%; } affiche le image non rétréci. Je n'ai aucune idée des valeurs de hauteur et de largeur avec lesquelles vous travaillez, alors remplacez les vôtres. J'ai dû utiliser cette solution quand la solution $ (window) .load s'est avérée inefficace - alors maintenant j'utilise les deux. Cela vaut mieux que de régler les dimensions de l'image, car elle glisse dans un environnement fluide et sensible.