IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

jQuery Discussion :

Optimisation d'un script de diaporama aléatoire


Sujet :

jQuery

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté Avatar de eckerdecker
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 134
    Par défaut Optimisation d'un script de diaporama aléatoire
    Bonjour,

    Comme il est dit dans le titre, ce script n'a pas de problèmes particuliers que je n'arriverais pas à résoudre. Je le poste pour recueillir vos avis, vos suggestions, vos idées d'améliorations et/ou d'optimisation.

    Il s'agit d'un diaporama d'images (comme il en existe des tas déjà tout fait surement, mais c'est formateur de faire soi-même aussi) dont voici les caractéristiques :
    1/ Les images qui vont défiler se trouvent dans un dossier à part et toutes les images de ce dossier apparaitront dans le diaporama.
    2/ Il n'y a pas de répétition d'une image tant que toutes les images ne sont pas apparues une fois.
    3/ Les images apparaissent dans un ordre aléatoire.
    4/ La transition entre deux images est de type fondu enchainé.

    Commençons :

    Le HTML :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/tr/xhtml1/Dtd/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Diaporama aléatoire (PHP/HTML/CSS/Javascript/jQuery)</title>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
        <script type="text/javascript" src="jqueryTimers.js"></script>
        <script type="text/javascript" src="diaporama.js"></script>
        <link rel="stylesheet" media="screen" type="text/css" href="diaporama.css" />
      </head>
      <body>
        <div id="random">
          <img src="loading.gif" class="loading" alt="loading" />
        </div>
      </body>
    </html>
    Rien de bien méchant, à noter quand même l'utilisation du plugin jqueryTimers.

    Le CSS :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /* Fichier diaporama.css */
    #random {
      /* Il est préférable que les images fassent la taille du conteneur */
      width:450px; height:280px;
      background-repeat:no-repeat;
      background-position:top left;
      border:20px solid #ddd;
      background-color:#ddd;
      overflow:hidden;
      text-align:center;
    }
    #random img {
      border:0;
      margin:0;
    }
    #random img.loading {
      /* pour centrer verticalement le loading.gif (32x32px) */
      margin-top:124px;
    }
    On place les images du diaporama dans un dossier à part, par exemple random/ et dans ce dossier on met le script PHP suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <?php
    /* Fichier random/images.php */
    header('content-type: application/xml');
    echo '<?xml version="1.0" encoding="utf-8" ?>';
    echo '<xml>';
    $dir = opendir('.');
    while($f = @readdir($dir)){
      if(!is_dir($f)){
        $ext = strrchr($f,'.');
        if($ext == ".jpg" || $ext == ".png" || $ext == ".gif")
          echo '<img src="'.dirname($_SERVER["SCRIPT_NAME"]).'/'.$f.'" />';
      }
    }
    closedir($dir);
    echo '</xml>';
    Ce script va lister les images (limitées aux gif, jpg et png) du dossier dans lequel il se trouve et rendre une réponse XML de ce type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <?xml version="1.0" encoding="utf-8" ?>
    <xml>
      <img src="/random/image.gif" />
      <img src="/random/picture.png" />
      <img src="/random/illustration.jpg" />
    </xml>
    Enfin, le gros du boulot, j'ai commenté un peu le code : le javascript/jQuery
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    /* Fichier diaporama.js */
     
    // Tableau des images à afficher
    var vDiapoRandImgs = new Array();
    // Tableau des images déjà affichées
    var vDiapoRandDisplayed = new Array();
    // Durée d'apparition d'une image
    var vDiapoRandDelay = 3000;// ms
    // Vitesse de la transition
    var vDiapoRandTransition = 500;//ms
    // Nombre d'images du diaporama
    var vDiapoRandLength = 0;
    // Nombre d'images chargées
    var vDiapoRandLoaded = 0;
     
    $(function(){
      $.ajax({
        type: "GET",
        url: "random/images.php",
        dataType: "xml",
        success: function(xml){
          vDiapoRandLength = $(xml).find('img').length;
          $(xml).find('img').each(function(){
            vDiapoRandImgs.push(new Image());
            vDiapoRandImgs[vDiapoRandImgs.length-1].onload = function(){
              vDiapoRandLoaded += 1;
              if(vDiapoRandLoaded == vDiapoRandLength) {
                // Disparition du loading.gif
                $('#random img').fadeOut(vDiapoRandTransition, function(){
                  $('#random img').removeClass('loading');
                  // Tirage aléatoire de la première image
                  $('#random img').attr('src', getRandomImg());
                  // Apparition de la première image
                  randFadeIn();
                });
              }
            }
            vDiapoRandImgs[vDiapoRandImgs.length-1].src = $(this).attr('src');
          });
        }
      });
    });
     
    // Tirage aléatoire d'une image
    function getRandomImg() {
      var i_img = 0;
      // Si toutes les images sont passées
      if(vDiapoRandImgs.length == 0) {
        vDiapoRandImgs = vDiapoRandDisplayed;
        vDiapoRandDisplayed = new Array();
        // Tirage aléatoire d'une image, en évitant la dernière qui est en cours
        i_img = Math.floor(Math.random()*vDiapoRandImgs.length-1);
      }
      else
        i_img = Math.floor(Math.random()*vDiapoRandImgs.length);
      var img = vDiapoRandImgs[i_img];
      vDiapoRandDisplayed.push(img);
      vDiapoRandImgs.splice(i_img, 1);
      return img.src;
    }
     
    // Disparition de l'image <img> puis changement de son attribut src
    function randFadeOut() {
      $('#random img').fadeOut(vDiapoRandTransition, function(){
        $('#random img').attr('src', getRandomImg());
        $('#random').oneTime(vDiapoRandDelay, randFadeIn);
      });
    }
     
    // Apparition de l'image <img> puis changement du background du conteneur
    function randFadeIn() {
      $('#random img').fadeIn(vDiapoRandTransition, function(){
        $('#random').css('background-image', 'url(' + getRandomImg() + ')');
        $('#random').oneTime(vDiapoRandDelay, randFadeOut);
      });
    }
    Voilà, en espérant que vous aurez eut le courage d'aller au bout .
    Parmi les améliorations que j'envisage d'apporter :
    1/ En faire un plugin jQuery, je ne me suis pas encore vraiment intéressé au "Comment" mais j'aimerai beaucoup savoir en écrire un.
    2/ M'affranchir du plugin jqueryTimers.
    3/ Réaliser les transitions autrement qu'avec cette dualité background/contenu, tout en restant compatible IE6, cela permettrait d'inclure d'autres modes de transitions.

    Voilà ! N'hésitez pas à donner votre avis

  2. #2
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Billets dans le blog
    125
    Par défaut
    Bonsoir

    J'ai repris votre code en l'optimisant et en le modifiant un peu.

    Comme nous sommes dans un sous-forum JavaScript, j'ai utilisé directement un fichier XML comme source de données.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?xml version="1.0" encoding="UTF-8"?>
    <xml>
      <img src="../images/imageTest.png" />
      <img src="../images/menu_dossiers.png" />
      <img src="../images/menu_forums.png" />
      <img src="../images/menu_gsp.png" />
      <img src="../images/menu_infos.png" />
      <img src="../images/menu_accueil.png" />
      <img src="../images/menu_resultat.png" />
      <img src="../images/avatarDVJH.jpg" />
      <img src="../images/jQuery-alpha-trans.png" />
    </xml>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    <!doctype html>
    <html lang="fr">
    <head>
    	<meta charset="utf-8">
    	<meta name="Author" content="Daniel Hagnoul">
    	<title>Forum jQuery</title>
    	<style>
    		/* BASE */
    		body {
    			background-color:#dcdcdc;
    			color:#000000;
    			font-family:sans-serif;
    			font-size:medium;
    			font-style:normal;
    			font-weight:normal;
    			line-height:normal;
    			letter-spacing:normal;
    		}
    		h1,h2,h3,h4,h5 {
    			font-family:serif;
    		}
    		div,p,h1,h2,h3,h4,h5,h6,ul,ol,dl,form,table,img {
    			margin:0px;
    			padding:0px;
    		}
    		p {
    			padding:6px;
    		}
    		ul,ol,dl {
    			list-style:none;
    			padding-left:6px;
    			padding-top:6px;
    		}
    		li {
    			padding-bottom:6px;
    		}
     
    		/* dvjh */
    		h1 {
    			text-align:center;
    			font-style:italic;
    			text-shadow: 4px 4px 4px #bbbbbb;
    		}
    		h2 {
    			text-align:center;
    		}
    		div#conteneur {
    			width:95%;
    			height:auto;
    			margin:12px auto;
    			padding:6px;
    			background-color:#FFFFFF;
    			color:#000000;
    			border:1px solid #666666;
    		}
    		div#affiche {
    			clear:both;
    			margin:12px;
    			padding:6px;
    			border:1px solid #999999;
    			background-color:#FFFFFF;
    			color:#000000;
    		}
     
    		/* TEST */
    		#random {
    			width:300px;
    			height:300px;
    			margin:12px;
    			padding:6px;
    			overflow:hidden;
    			text-align:center;
    			border:1px dotted grey;
    		}
    		#randImgID {
    			border:0px;
    		}
    		#randImgID.loading {
    			margin-top:124px;
    		}
    	</style>
    	<script charset="utf-8" src="../lib/jqueryui/js/jquery-1.4.2.min.js"></script>
     	<script>
    		// retourne X tel que : min <= X <= max
    		function intRandom(min, max){
    			return Math.floor(Math.random() * (max - min + 1) + min);
    		}
     
    		// retourne un array dans un ordre aléatoire
    		function brouille(tab){
    			var pos, temp;
     
    			for (var j = tab.length - 1; j > 0; j--){
    				pos = intRandom(0, j + 1);
    				temp = tab[j];
    				tab[j] = tab[pos];
    				tab[pos] = temp;
    			}
     
    			return tab;
    		}
     
    		var fadingDelay = 1000;
    		var setTimeoutDelay = 2000;
    		var images = [];
    		var taille, n;
     
    		$(function(){
    			$.get("listImg.xml", function(xml) {
    				$(xml).find('img').each(function(i, item){
    					images.push(new Image());
    					$(images[i]).attr("src", $(item).attr("src")).load();
    				});
     
    				brouille(images);
    				taille = images.length - 1;
    				n = taille;
     
    				$("#randImgID").fadeOut(fadingDelay, function(){
    					$(this).removeClass("loading").attr("src", $(images[n]).attr("src"));
    					randFadeIn()
    				});
    			}, "xml");
    		});
     
    		function randFadeOut(){
    			$("#randImgID").fadeOut(fadingDelay, function(){
    				$(this).attr("src", $(images[n]).attr("src"));
    				randFadeIn()
    			});
    		}
     
    		function randFadeIn(){
    			$("#randImgID").fadeIn(fadingDelay, function(){
     
    				if (n < 1){
    					n = taille;
    					brouille(images);
    				} else {
    					--n;
    				}
     
    				window.setTimeout(randFadeOut, setTimeoutDelay);
    			});
    		}
    	</script>
    </head>
    <body>
    	<h1>Forum jQuery</h1>
    	<div id="conteneur">
    		<h2>Affichage perpétuel d'un lot d'images. Elles sont toujours présentées dans un ordre aléatoire.</h2>
    		<div id="random">
    		  <img id="randImgID" src="../images/load.gif" class="loading" alt="loading" />
    		</div>
     
    		<div id="affiche"></div>
    	</div>
    </body>  
    </html>

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  3. #3
    Membre expérimenté Avatar de eckerdecker
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 134
    Par défaut
    Bonjour,

    Il y a des chose qui m'intéresse dans votre version, comme la syntaxe simplifiée pour le get ajax, le chargement des images ou encore l'absence de jqueryTimers.

    Par contre je m'interroge sur d'autre points.

    1/ le diaporama n'est il pas démarré sans savoir si toutes les images sont complétement chargées ?
    2/ entre votre méthode de gestion de l'aléatoire et de le non redondance et la mienne, sur quel point particulier l'optimisation était-elle nécessaire ?

    Enfin pour ce qui est de la dualité background/image pour la transition je pensais plutôt essayer d'obtenir le même effet de transition avec deux <img> par exemple, et jouer sur un positionnement absolu (pas de relatif, ie6 n'aime pas ça) et du z-index. Ensuite avec deux <img> on peut imaginer des transitions type translation droite-gauche ou haut-bas.

    Note : je ne demande pas qu'on me fasse le boulot, je donne mes idées, j'en demande, j'apporterai les modifications d'ici peu

  4. #4
    Futur Membre du Club
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2012
    Messages : 5
    Par défaut
    Bonjour, je suis bien debutante dans tout ca... J'ai pour ma part suivi à la lettre la procédure du premier post, mais quand j'affiche ma page j'ai juste un carré de la taille de l'image, avec ecrit "loading"... Puis la 1e image; qui semble masquer les autres...
    Voici http://locationmimizanplage.free.fr/diapo/diapo.html

  5. #5
    Membre expérimenté Avatar de eckerdecker
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 134
    Par défaut
    Bonjour,

    Il manque le plugin jQuery.timers que tu trouveras ici http://jquery.offput.ca/js/jquery.timers.js

    Une des raisons de mon post était de m'en passer, je n'ai pas refait de version depuis mais le post de danielhagnoul peut t'y aider.

    Sinon une remarque à propos du code php, il m'est arrivé d'avoir des soucis sur des sites en production avec le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dirname($_SERVER["SCRIPT_NAME"])
    Je préfère mettre le chemin en dur c'est plus sûr. Sinon un simple fichier XML fait l'affaire comme le dit danielhagnoul. L’intérêt du script php est de permettre à une tierce personne de modifier les images du dossier, d'en ajouter et d'en supprimer, sans se préoccuper d'un fichier XML à maintenir à jour.

  6. #6
    Futur Membre du Club
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2012
    Messages : 5
    Par défaut
    Bonjour, merci pour la réponse. Mon fichier jquerytimer est présent; et apparemment mon repertoire est bon car les photos sont là : on voit la premiere, mais on dirait que ca masque les autres.
    Je n'ai pas fait de fichier XML; est ce ca le problème??

    ...............

Discussions similaires

  1. [MySQL] Besoin d'aide pour optimisation d'un script très lourd
    Par macadamgrafik dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 25/02/2009, 16h08
  2. Optimisation d'un script d'analyse
    Par azerwhite dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 6
    Dernier message: 21/10/2008, 09h48
  3. Réponses: 6
    Dernier message: 23/01/2007, 17h20
  4. Petit script d'images aléatoires avec lien
    Par Syntax-ERROR dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 09/01/2007, 21h43
  5. lancer un script de manière aléatoire
    Par emilie75 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 15/09/2006, 10h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo