Jquery Cycle + Firefox Squishing Images

Hé les gars, je cours jQuery Cycle pour une galerie d'images. Voir le lien: ici

Mon problème est que les images sont épuisé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 déclencher avant que toutes les images ne soient chargées (généralement la première image fonctionne bien et le reste est écrasé).

Un re-nouveau dur reproduit le problème.

J'ai enveloppé tout dans un $ (document) .ready (function () {}); Mais il arrive toujours.

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

Je suis très 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>'; } });});}); 

Il y a une solution beaucoup plus simple et plus propre que j'ai utilisé pour 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, modifiez ceci:

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

Pour ça:

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

Pourquoi cela fonctionne-t-il? Parce que window.onload déclenche une fois que toutes les images référencées sur la page sont chargées (voir https://developer.mozilla.org/fr/DOM/window.onload , et .load () – jQuery API ), qui est le comportement souhaité dans ta situation. $(document).ready , mieux connu sous le nom "DOM Ready", 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.

J'ai eu le même problème lors du travail sur un site il y a plusieurs mois (ci-dessous). Si vous démarrez un cycle en $(document).ready() , voici ce qui se passe lorsqu'un client parcourt 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 ne soient terminées, le cycle commence. Le cycle fonctionne en cachant tout sauf la première image dans le diaporama: il définit la visibility:hidden et display:none sur chacune de ses images.

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

J'ai résolu cela en changeant mon code afin qu'il ne démarre pas le plugin de cycle jusqu'à ce que toutes les images soient terminées. Pour ce faire, j'initialise une variable de compteur sur le nombre d'images que je fais, puis lier un événement de chargement à 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 consultant les galeries sur ce site dans Firefox. Je construis les pages de la galerie de façon dynamique, de sorte que c'est structuré un peu différemment que ta page, mais tu vois plus de détails si tu fais de la souris avec Firebug.

J'aimerais également ajouter qu'il semble ajouter un attribut largeur et hauteur pour résoudre ce problème.

Ok, je sais que c'est probablement une façon horrible d'appeler la charge, mais je ne peux que lier mon code de cycle à .load pour une raison pour laquelle il ne fonctionne pas, alors j'ai appelé l'initialiseur Cycle complet à l'intérieur …

Je ne pouvais pas forcer les tailles puisque je fais du vélo via li contenant des images et des données dynamiques

C'est sans doute à l'écart, mais pour ceux qui sont désespérés comme moi …

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

Je pense que je l'ai modifié légèrement pour gérer les pages où vous ne connaissez pas le nombre total d'images. Il semble fonctionner bien pour moi, si quelqu'un peut voir des défauts, veuillez les signaler – j'apprends toujours.

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

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 étiquette img.

Vous pouvez utiliser une solution semblable à la création de vidéos youtube réactives. Vous devez connaître le ratio de votre largeur en hauteur, et ajouter cela comme fond de rembourrage à la division cycliste. Pour mes photos 1024X680, j'ai utilisé 680/1024 = 66,4%

Dans votre cas, je crois

#slideshow{ padding-bottom:66.4%; } #slideshow{ padding-bottom:66.4%; } Affichera l'image sans interruption. Je n'ai aucune idée de la hauteur réelle et des valeurs de largeur avec lesquelles vous travaillez. Substituez donc le vôtre. J'ai dû utiliser cette solution lorsque la solution $ (window) .load s'est révélée irrégulière et inefficace – alors j'utilise les deux.

C'est mieux que de définir les dimensions de l'image, car elle se glisse dans un environnement fluide et réactif.