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

JavaScript Discussion :

Convertir mon script en objet instanciable


Sujet :

JavaScript

  1. #1
    Membre confirmé
    Inscrit en
    Septembre 2003
    Messages
    108
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 108
    Par défaut Convertir mon script en objet instanciable
    :hello:

    J'ai fait un petit script qui fonctionne. Voici en gros la tête qu'il a :

    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
     
    var Diaporama = {
    	version: "1.0",
    	param1: "valeurParDefaut1",
    	param2: "valeurParDefaut2",
     
    	fonction1: function(img) {
    		// fait quelque chose
    	},
     
    	fonction2: function(img) {
    		// fait quelque chose
    	},
     
    	init: function (el, options) {
    		this.element = $(el);
    		this.param1 = options.param1;
    		this.param2 = options.param2;
     
    		$("img." + this.thumbClass).click(function() {
    			Diaporama.fonction1(this);
    		});
    	}
    }
    Et voici comment je l'appelle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Diaporama.init("#monElement", {param1: "valeur1", param2: "valeur2"});
    Sauf que j'aimerais pouvoir l'appeler plusieurs fois dans la même page en changeant les paramètres. Il faudrait que je puisse l'instancier. Ca devrait donner un truc comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    diapo1 = new Diaporama("#monElement", {param1: "valeur1", param2: "valeur2"});
    diapo2 = new Diaporama("#monAutreElement", {param1: "valeur3", param2: "valeur4"});
    Seulement je ne sais pas vraiment comment faire. Ca doit être un truc que les pros de l'Ajax font tout le temps, mais je ne sais pas comment m'y prendre. Pour info j'utilise jQuery. Avez-vous une idée ?

    Merci !

  2. #2
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Billets dans le blog
    20
    Par défaut
    Qu'est-ce qui ne fonctionne pas ?
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  3. #3
    Membre confirmé
    Inscrit en
    Septembre 2003
    Messages
    108
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 108
    Par défaut
    Le script fonctionne, mais j'aimerais pouvoir l'instancier pour l'utiliser plusieurs fois dans la même page.

  4. #4
    Inactif  

    Profil pro
    Inscrit en
    Mai 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 345
    Par défaut
    Citation Envoyé par Shuret Voir le message
    Le script fonctionne, mais j'aimerais pouvoir l'instancier pour l'utiliser plusieurs fois dans la même page.
    De la manière où tu as écrit ton script, tu as fait directement un objet instancié et non une classe

    Un manière toute conne et rapide de transformer ton truc en objet instanciable est celle-ci :

    ATTENTION : regarde bien les commentaires et comment je procède aux endroits ou tu appelles Diaporama.
    Puisque maintenant on parle d'instance.

    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
    //déclaration de la Classe Diaporama et de son constructeur
    var Diaporama = function() {
        this.init.apply(this,arguments); //on appelle init puisqu'apparament c'est la méthode d'initialisation.
    }
    //déclaration du prototype de cette classe :
    Diaporama.prototype = {
        constructor:Diaporama, //ne pas oublier cette ligne, sinon le constructeur sera "Object"
     
        version: "1.0",
        param1: "valeurParDefaut1",
        param2: "valeurParDefaut2",
     
        fonction1: function(img) {
            // fait quelque chose
        },
     
        fonction2: function(img) {
            // fait quelque chose
        },
     
        init: function (el, options) {
            //creation d'une variable faisant référence à this pour qu'elle puis être utilisée dans les fonctions qui sont déclarées dans le init.
            var _this = this;
            this.element = $(el);
            this.param1 = options.param1;
            this.param2 = options.param2;
     
            //ici ce n'est pas bon, tu tapes sur tout ce qui est .imgQuelqueChose. Il faudrait partir de ton élément parent, puisque c'est lui qui contient les images
            this.element.find("img." + this.thumbClass).click(function() {
                _this.fonction1(this); //on remplace Diaporama par _this
            });
        }
    }

  5. #5
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Par défaut
    @Shuret Si tu utilise JQuery je te recommande vivement de faire
    un plugin

    Actuellement tu appelles ton code ainsi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Diaporama.init("#monElement", {param1: "valeur1", param2: "valeur2"});
    A la sauce JQuery tu pourra l'appeler ainsi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $('#monElement').diaporama({param1: "valeur1", param2: "valeur2"});
    Et mieux encore, tu pourra appliquer plusieurs diaporama en une ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $('img.diapo').diaporama({ param1: "valeur1", param2: "valeur2"});
    Lit ce tuto

    Si besoin, je t'aide volontier

  6. #6
    Inactif  

    Profil pro
    Inscrit en
    Mai 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 345
    Par défaut
    Citation Envoyé par marcha Voir le message
    @Shuret Si tu utilise JQuery je te recommande vivement de faire
    un plugin

    Actuellement tu appelles ton code ainsi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Diaporama.init("#monElement", {param1: "valeur1", param2: "valeur2"});
    A la sauce JQuery tu pourra l'appeler ainsi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $('#monElement').diaporama({param1: "valeur1", param2: "valeur2"});
    Et mieux encore, tu pourra appliquer plusieurs diaporama en une ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $('img.diapo').diaporama({ param1: "valeur1", param2: "valeur2"});
    Lit ce tuto

    Si besoin, je t'aide volontier
    J'étais aussi en train de me demander s'il valait mieux pas qu'il transforme son truc en plugin jquery, mais du coup j'ai préféré répondre à la question

  7. #7
    Membre confirmé
    Inscrit en
    Septembre 2003
    Messages
    108
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 108
    Par défaut
    @dukej & marcha :

    Voilà, c'est exactement ce que je recherche, merci !

    Je vais essayer de l'implémenter et je vous tiens au courant.

    Petite question :
    Le code "Diaporama.prototype = {" c'est du Javascript pur ? Le mot prototype me file un doute... Si oui, je peux l'utiliser indépendamment du framework (jQuery ou Prototype en général) que j'utilise ? Au contraire du tuto de marcha qui est spécifique à jQuery si j'ai bien compris.

  8. #8
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Par défaut
    prototype est une propriété standard javascript de l'objet Function. A ne
    pas confondre avec le framework Prototype.js (un peu similaire au framework
    JQuery)

  9. #9
    Membre confirmé
    Inscrit en
    Septembre 2003
    Messages
    108
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 108
    Par défaut
    Merci pour le renseignement !

    Voilà mon code final, qui fonctionne plutôt bien :
    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
     
    // Déclaration du plugin
    (function($) {
    	$.fn.Diaporama = function(options) {
     
      	// Paramètres par défaut
      	var defaultSettings = {
      		fullSizeImage: "#fullSizeImage",
      		enlargeDescription: "Click to enlarge"
      	};
     
    		// Fusion des paramètres utilisateur et des paramètres par défaut
    		if (options) {
    			options = $.extend(defaultSettings, options);
    		}
     
    		// Traverser tous les noeuds
    		this.each(function() {
     
    			getOriginalImageSize = function(img) {		    
    				var tmp = new Image();
    				tmp.src = img.attr("src");
    				return [tmp.width, tmp.height];
    			};
     
    			var imgBackWidth, imgFrontWidth;
    			var imgFrontMarginLeft, imgBackMarginLeft, topPos;
    			var imgFront, imgBack, imgFrontId;
    			var borderSize;
    			var description;
    			var $this;
     
    			$this = $(this);
     
    			imgFront = $(options.fullSizeImage);
    			imgFrontId = imgFront.attr("id");
     
    			// Récupération de la description
    			description = $.trim($this.attr("alt").replace(options.enlargeDescription, ""));
     
    			// Récupération de la largeur de la bordure
    			borderSize = (imgFront.css("borderTopWidth")).replace("px", "");
     
    			// Récupération de la taille d'origine de l'image
    			imgBackWidth = getOriginalImageSize($this)[0];
     
    			// Récupération de la taille de l'image en premier plan
    			imgFrontWidth = Number(imgFront.attr("width"));
     
    			// Calcul des positions
    			topPos = imgFront.offset().top;
    			imgFrontMarginLeft = -Math.floor((imgFrontWidth + borderSize * 2)/2);
    			imgBackMarginLeft = -Math.floor((imgBackWidth + borderSize * 2)/2);
     
    			// Création d'un clone
    			imgBack = imgFront.clone();
    			imgBack.css({position: 'absolute', marginLeft: imgBackMarginLeft + 'px', 'top': topPos + 'px', 'left': '50%', 'opacity': 0})
    			imgBack.attr("src", $this.attr("src"));
    			imgBack.attr("id", imgFrontId + "Back");
     
    			// Fondu enchainé
    			imgFront.css({position: 'absolute', marginLeft: imgFrontMarginLeft + 'px', 'top': topPos + 'px', 'left': '50%'}).after(imgBack).animate({opacity: 0}, 500);
    			imgBack.animate({opacity: 1}, 500, function deleteImage() {
    				imgFront.remove();
    				imgBack.attr("title", description);
    				imgBack.attr("alt", description);
    				imgBack.attr("id", imgFrontId);
    			});
     
    		});
     
    		// Permettre le chaînage par jQuery
    		return this;
     
    	};
     
    })(jQuery);
    Et on l'appelle comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    $("img.thumb").click(function() {
    	$(this).Diaporama({fullSizeImage: "#fullSizeImage2", enlargeDescription: "[Cliquez pour agrandir]"});
    });
    Bon ça casse pas des briques, mais ça me fait un bon exercice pour me familiariser avec jQuery.

    J'aurais d'autres questions :
    Le placement de la fonction getOriginalImageSize est-il optimal ? Faut-il la mettre hors du plugin ? Quelles sont les bonnes pratiques pour ce genre de fonction indépendante ?

    J'applique ce plugin au click sur certains éléments. Du coup j'ai un code du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $(document).ready(function() {
    	$("img.thumb").click(function() {
    		$(this).Diaporama({enlargeDescription: " [Cliquez pour agrandir]"});
    	});
    });
    Est-ce que je peux m'affranchir du document.ready ? L'idéal serait de l'appeler ce cette façon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $('img.thumb').Diaporama({enlargeDescription: " [Cliquez pour agrandir]"});
    et d'ajouter dans le plugin que c'est sur un click une fois le document prêt.

    D'autre part, si vous voyez des erreurs grossières dans mon code ou des aberrations, je suis preneur.

    Merci pour votre aide !

  10. #10
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Par défaut
    Salut,

    Pour la fonction, pas de raison de la mettre dehors.
    N'oublie pas le var devant pour qu'elle soit locale.

    La fonction pourrait se passer de paramètre dans ton
    exemple car elle voit les variables de la fonction dans
    laquelle elle est déclarée.

    Tu peux en effet assigner l'évènement dans ton plugin

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    this.each(function() {
       var $this = this; // perso je préfère var obj = this;
       $this.click(function(event) {
          ... tout le code ici
       });
    });
    Si tu veux pas utiliser document.ready tu devra placer le code
    d'initialisation après les éléments DOM concernés dans ta page,
    ce qui n'est pas pratique en général.

  11. #11
    Membre confirmé
    Inscrit en
    Septembre 2003
    Messages
    108
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 108
    Par défaut
    J'ai mis à jour le code avec tes conseils. J'ai dû utiliser var "img = $(event.target);" pour référencer l'image sinon ça ne fonctionnait pas. Est-ce correct ?

    J'ai ajouté un booléen pour éviter de lancer le script 2 fois avant qu'il ne soit terminé (variable inProgress). Je l'ai placée au début, afin qu'elle se comporte un peu comme une variable static. Ca fonctionne mais est-ce une bonne façon de faire ?

    Pour le document.ready, je voudrais qu'il soit géré par le script. Maintenant je l'appelle avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $(document).ready(function() {
    $("img.thumb").Diaporama({enlargeDescription: " [Cliquez pour agrandir]"});
    });
    ce qui est pas mal, mais il doit être possible de ne mettre que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $("img.thumb").Diaporama({enlargeDescription: " [Cliquez pour agrandir]"});
    D'autant plus que j'aimerais ajouter une initialisation à mon script : en créant un nouveau diaporama, je remplace le parent contenant les thumbs par un gif animé d'attente le temps de charger toutes les images (donc à la fin du document.ready), j'ajoute le handler sur le click de $("img.thumb") et différents autres trucs. Il faudrait en gros déporter l'évènement document.ready dans le diaporama, mais je ne vois pas comment faire.

    Voici le code à jour :
    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
     
    // Déclaration du plugin
    (function($) {
     
    	var inProgress = false;
     
    	$.fn.Diaporama = function(options) {
     
      	// Paramètres par défaut
      	var defaultSettings = {
      		fullSizeImage: "#fullSizeImage",
      		enlargeDescription: "Click to enlarge"
      	};
     
    		// Fusion des paramètres utilisateur et des paramètres par défaut
    		if (options) {
    			options = $.extend(defaultSettings, options);
    		}
     
    		// Traverser tous les noeuds
    		this.each(function() {
     
    			var $this = $(this);
     
    			$this.click(function(event) {
     
    				var imgBackWidth, imgFrontWidth;
    				var imgFrontMarginLeft, imgBackMarginLeft, topPos;
    				var imgFront, imgBack, imgFrontId;
    				var borderSize;
    				var description;
     
    				var img = $(event.target);
     
    				var getOriginalImageSize = function() {		    
    					var tmp = new Image();
    					tmp.src = img.attr("src");
    					return [tmp.width, tmp.height];
    				};
     
    				// Empècher le script d'être lancé plusieurs fois en même temps
    				if (inProgress) {
    					return;
    				}
     
    				inProgress = true;
     
    				imgFront = $(options.fullSizeImage);
    				imgFrontId = imgFront.attr("id");
     
    				// Récupération de la description
    				description = $.trim(img.attr("alt").replace(options.enlargeDescription, ""));
     
    				// Récupération de la largeur de la bordure
    				borderSize = (imgFront.css("borderTopWidth")).replace("px", "");
     
    				// Récupération de la taille d'origine de l'image
    				imgBackWidth = getOriginalImageSize(img)[0];
     
    				// Récupération de la taille de l'image en premier plan
    				imgFrontWidth = Number(imgFront.attr("width"));
     
    				// Calcul des positions
    				topPos = imgFront.offset().top;
    				imgFrontMarginLeft = -Math.floor((imgFrontWidth + borderSize * 2)/2);
    				imgBackMarginLeft = -Math.floor((imgBackWidth + borderSize * 2)/2);
     
    				// Création d'un clone
    				imgBack = imgFront.clone();
    				imgBack.css({position: 'absolute', marginLeft: imgBackMarginLeft + 'px', 'top': topPos + 'px', 'left': '50%', 'opacity': 0})
    				imgBack.attr("src", img.attr("src"));
    				imgBack.attr("id", imgFrontId + "Back");
     
    				// Fondu enchainé
    				imgFront.css({position: 'absolute', marginLeft: imgFrontMarginLeft + 'px', 'top': topPos + 'px', 'left': '50%'}).after(imgBack).animate({opacity: 0}, 500);
    				imgBack.animate({opacity: 1}, 500, function deleteImage() {
    					imgFront.remove();
    					imgBack.attr("title", description);
    					imgBack.attr("alt", description);
    					imgBack.attr("id", imgFrontId);
    					inProgress = false;
    				});
     
    			});
     
    		});
     
    		// Permettre le chaînage par jQuery
    		return this;
     
    	};
     
    })(jQuery);

  12. #12
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Par défaut
    Salut,

    je suis surpris que tu aie du écrire: var img = $(event.target);
    normalement var img = $(this); ou même var img = $this; devraient
    être équivalant dans ton cas. Peux tu vérifier ?

    Pour ce qui est de document.ready il faut pas confondre avec body onload
    document.ready est un évènement 'artificiel' que jquery déclenche quand
    le DOM est prêt. C'est à dire que le code HTML de la page est au complet,
    près à l'emploi. A ce moment là, les images sont probablement pas encore
    chargées. Le body onload est déclenché quand toutes les ressources sont
    chargées (images, styles, javascript, ...)

    En général tu as au moins un document.ready dans une application qui
    utilise JQuery

    On peut l'abréger ainsi aussi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $(function() {
    $("img.thumb").Diaporama({enlargeDescription: " [Cliquez pour agrandir]"});
    });
    A mon avis ton inProgress sert à rien, javascript n'est pas multithread on
    ne peut pas appeler deux fonctions en "même temps"

  13. #13
    Membre confirmé
    Inscrit en
    Septembre 2003
    Messages
    108
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 108
    Par défaut
    Effectivement, "var img = $this;" fonctionne. Je sais pas ce que j'ai foutu

    L'équivalent du body onload semble être $(window).load. Je pourrais appeler la création des diaporamas dans le document.ready (où la div contenant les thumbs serait remplacée par un gif d'attente) et dans le code du diaporama, il y aurait un $(window).load qui remplacerait le gif d'attente par les images une fois celles-ci chargées. Seulement je ne sais pas comment faire pour appeler une seule fois $(window).load (c'est appelé autant de fois que de diaporamas). De plus j'ai besoin de le mettre dans le corps du script car j'utilise les valeurs de "options" et l'élément cliqué.

    Il faudrait caser tout ça dans une fonction d'initialisation. Dans le document.ready de la page web : appel de la fonction d'init qui ajoute les handlers du clic, initialise quelques trucs et remplace les thumbs par un gif d'attente. Une fois le chargement complet (avec les images), pour tous les diaporamas, remplacement des gif d'attente par les images. C'est possible ? Je ne sais pas vraiment comment m'y prendre. As-tu une piste ?

    Pour le inProgress, le problème est que le script se déclenche sur le click d'un des éléments. On peut donc cliquer sur un autre élément avant que le callback final du premier ne soit terminé. Dans ce cas, j'ai plusieurs éléments avec le même ID et ça plante.

  14. #14
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Par défaut
    Pourrais tu poster un exemple complet, code HTML + js ou alors un exemple hébergé, je vois des idées de simplification, mais
    ça m'aiderait d'avoir le html aussi.

  15. #15
    Membre confirmé
    Inscrit en
    Septembre 2003
    Messages
    108
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 108
    Par défaut
    Voici le js au complet :
    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
     
    // Déclaration du plugin
    (function($) {
     
    	var inProgress = false;
     
    	$.fn.Diaporama = function(options) {
     
    		// Paramètres par défaut
    		var defaultSettings = {
    			fullSizeImage: "#fullSizeImage",
    			EnlargeDescription: "Click to enlarge"
    		};
     
    		// Fusion des paramètres utilisateur et des paramètres par défaut
    		if (options) {
    			options = $.extend(defaultSettings, options);
    		}
     
    		// Traverser tous les noeuds
    		this.each(function() {
     
    			var $this = $(this);
     
    			$this.click(function(event) {
     
    				var imgBackWidth, imgFrontWidth;
    				var imgFrontMarginLeft, imgBackMarginLeft, topPos;
    				var imgFront, imgBack, imgFrontId;
    				var borderSize;
    				var description;
     
    				var img = $this;
     
    				var getOriginalImageSize = function() {		    
    					var tmp = new Image();
    					tmp.src = img.attr("src");
    					return [tmp.width, tmp.height];
    				};
     
    				// Empècher le script d'être lancé plusieurs fois en même temps
    				if (inProgress) {
    					return;
    				}
     
    				inProgress = true;
     
    				imgFront = $(options.fullSizeImage);
    				imgFrontId = imgFront.attr("id");
     
    				// Récupération de la description
    				description = $.trim(img.attr("alt").replace(options.enlargeDescription, ""));
     
    				// Récupération de la largeur de la bordure
    				borderSize = (imgFront.css("borderTopWidth")).replace("px", "");
     
    				// Récupération de la taille d'origine de l'image
    				imgBackWidth = getOriginalImageSize(img)[0];
     
    				// Récupération de la taille de l'image en premier plan
    				imgFrontWidth = Number(imgFront.attr("width"));
     
    				// Calcul des positions
    				topPos = imgFront.offset().top;
    				imgFrontMarginLeft = -Math.floor((imgFrontWidth + borderSize * 2)/2);
    				imgBackMarginLeft = -Math.floor((imgBackWidth + borderSize * 2)/2);
     
    				// Création d'un clone
    				imgBack = imgFront.clone();
    				imgBack.css({position: 'absolute', marginLeft: imgBackMarginLeft + 'px', 'top': topPos + 'px', 'left': '50%', 'opacity': 0})
    				imgBack.attr("src", img.attr("src"));
    				imgBack.attr("id", imgFrontId + "Back");
     
    				// Fondu enchainé
    				imgFront.css({position: 'absolute', marginLeft: imgFrontMarginLeft + 'px', 'top': topPos + 'px', 'left': '50%'}).after(imgBack).animate({opacity: 0}, 500);
    				imgBack.animate({opacity: 1}, 500, function deleteImage() {
    					imgFront.remove();
    					imgBack.attr("title", description);
    					imgBack.attr("alt", description);
    					imgBack.attr("id", imgFrontId);
    					inProgress = false;
    				});
     
    			});
     
    		});
     
    		// Permettre le chaînage par jQuery
    		return this;
     
    	};
     
    })(jQuery);
    Et la partie HTML simplifiée :
    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
     
    <?xml version="1.0" encoding="UTF-8" ?>
    <!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>
    <style type="text/css" media="screen">
    	@import 'css/diaporama.css';
    </style>
    <script type="text/javascript" src="js/jquery-1.4.2.js"></script>
    <script type="text/javascript" src="js/jquery.diaporama.js"></script>
    <script type="text/javascript">
    $(document).ready(function() {
    	$("#photos img.thumb").Diaporama({enlargeDescription: " [Cliquez pour agrandir]"});
    	$("#photos2 img.thumb").Diaporama({fullSizeImage: "#fullSizeImage2", enlargeDescription: "[Cliquez pour agrandir]"});
    });
    </script>
    </head>
     
    <body>
     
    		<div id="photos">
    			<img class="thumb" alt="Description [Cliquez pour agrandir]" title="Description [Cliquez pour agrandir]" src="img/photos/image1.jpg" />
    			<img class="thumb" alt="Description [Cliquez pour agrandir]" title="Description [Cliquez pour agrandir]" src="img/photos/image2.jpg" />
    			<img class="thumb" alt="Description [Cliquez pour agrandir]" title="Description [Cliquez pour agrandir]" src="img/photos/image3.jpg" />
    		</div>
     
    		<div id="bigPhoto">
    			<img id="fullSizeImage" class="fullSize" alt="" title="" src="img/photos/default.jpg" />
    		</div>
     
    		<div id="photos2">
    			<img class="thumb" alt="Description [Cliquez pour agrandir]" title="Description [Cliquez pour agrandir]" src="img/photos/image3.jpg" />
    			<img class="thumb" alt="Description [Cliquez pour agrandir]" title="Description [Cliquez pour agrandir]" src="img/photos/image4.jpg" />
    			<img class="thumb" alt="Description [Cliquez pour agrandir]" title="Description [Cliquez pour agrandir]" src="img/photos/image5.jpg" />
    		</div>
     
    		<div id="bigPhoto2">
    			<img id="fullSizeImage2" class="fullSize" alt="" title="" src="img/photos/default.jpg" />
    		</div>
     
    </body>
     
    </html>
    Le CSS pour que ça ressemble à quelque chose :
    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
     
    @CHARSET "UTF-8";
     
    #photos {
    	margin: 10px auto;
    	text-align: center;
    	border: #ddd 1px solid;
    	border-spacing: 10px;
    	border-collapse: collapse;
    }
     
    #photos2 {
    	margin: 10px auto;
    	text-align: center;
    	border: #ddd 1px solid;
    	border-spacing: 10px;
    	border-collapse: collapse;
    }
     
    #bigPhoto {
    	margin: 10px auto;
    	text-align: center;
    	height: 450px;
    	overflow: hidden; 
    }
     
    #bigPhoto2 {
    	margin: 10px auto;
    	text-align: center;
    	height: 450px;
    	overflow: hidden; 
    }
     
    img.thumb {
    	margin: 5px;
    	height: 120px;
    	border: #ddd 1px solid;
    }
     
    img.thumb:hover {
    	cursor: pointer;
    }
     
    img.fullSize {
    	border: #ddd 8px solid;
    	position: relative;
    	top: 0;
    	left: 0;
    }

  16. #16
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Par défaut
    Salut,

    Merci pour ton code, j'ai pu le tester chez moi, je vois mieux maintenant.

    Par contre je constate que tu utilises la grande image comme thumb que
    tu affiche en petit.

    Généralement on produit 2 images, une petite rapidement chargée et
    une grande, chargée à la demande au moment du click (ou éventuellement
    préchargée, mais après les petites)

    Qu'en penses-tu ?

  17. #17
    Membre confirmé
    Inscrit en
    Septembre 2003
    Messages
    108
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 108
    Par défaut
    Oui je sais bien !

    Disons que ce script est voué à être utilisé pour créer des diaporamas rapidement (par des non "spécialistes" du HTML) et je pensais qu'il était plus simple d'utiliser les mêmes images. Ca permet de ne pas avoir à charger l'image pour l'afficher en grand. Mais tu n'as pas tord...

    Je vais peut-être le modifier afin de remplacer les thumbs par des images légères avec un lien vers la grande image (pour que ce soit utilisable sans javascript) et utiliser un loader gif si l'image n'est pas chargée. Ou alors charger toutes les images dans des éléments invisibles (ou directement en javascript, mais comment ?) et attendre le window.load avant de handler le clic sur les thumbs.

    En tout cas cet exercice est formateur pour jQuery !

  18. #18
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Par défaut
    Pour l'image loader, une technique simple consiste à fixer
    le background-image de tes balises img avec un gif animé.
    L'image prendra naturellement place devant son fond quand
    elle sera chargée.

    Fixe aussi le min-width et min-height de la balise img pour que
    l'on voit le gif animé.

  19. #19
    Membre confirmé
    Inscrit en
    Septembre 2003
    Messages
    108
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 108
    Par défaut
    Pas bête !

    Mais min-height/min-width n'est pas supporté par IE6 (et malheureusement, il faudrait que ce soit compatible IE6). Je ne sais pas si j'aurai le temps de m'occuper de ce script la semaine prochaine, mais je posterai ici les MAJ si je l'ai. Merci pour ton aide en tout cas !

Discussions similaires

  1. erreur dans mon script
    Par Swata dans le forum Langage
    Réponses: 4
    Dernier message: 21/09/2005, 00h02
  2. [langage]erreur dans mon script
    Par Fabouney dans le forum Langage
    Réponses: 11
    Dernier message: 30/06/2005, 14h58
  3. Réponses: 7
    Dernier message: 04/06/2004, 15h20
  4. Tcsh - Mon script ne marche pas
    Par Aramis dans le forum Linux
    Réponses: 5
    Dernier message: 13/05/2004, 18h26
  5. Mon script cron n'est pas pris en compte
    Par tomnie dans le forum Linux
    Réponses: 11
    Dernier message: 31/03/2004, 11h19

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