Précédent   Forum des professionnels en informatique > Webmasters - Développement Web > JavaScript > Bibliothèques & Frameworks > jQuery
jQuery Forum d'entraide sur le framework jQuery. Avant de poster : Tutoriels jQuery, FAQ jQuery, Tous les tutoriels JavaScript, Toutes les FAQ JavaScript
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 22/01/2012, 22h36   #1
Candidat au titre de Membre du Club
 
Inscription : août 2008
Messages : 66
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 66
Points : 11
Points : 11
Par défaut Fonction qui se lance toute seule à plusieurs reprises ?

Bonsoir,
Je travaille avec le DOM en jquery, j'affiche des images uploadées par l'utilisateur, puis l'utilisateur peut les supprimer de l'écran (en cliquant sur une petite croix rouge, image dont la classe est delete). Sauf que je ne sais pas pourquoi, la fonction de suppression est parfois exécutée plusieurs fois, alors qu'appelée une seule fois !

voici mon code commenté :

Code :
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
			var compteur=0;
			$(document).ready(function()
			{   
 
			var options ={
					dataType:  'json', 
					beforeSubmit: function(){
					$('#loader').html('<img src="img/loading.gif" id="waiting">'); // L'animation de chargement
					},
					success:function(data){
 
						$('#waiting').remove(); // on supprime l'animation de chargement
						// Si erreur est set à 1... on annule et on prévient
						if(data.erreur=='1'){
							$('#results').html(data.message); // On affiche le message d'erreur dans la div
						}
						// Si l'upload s'est bien passé, on affiche l'image
						else{
							Ajouter_photo(data.image); // ici data.image est le chemin vers mon image
						}
					}
				}
				// fonction qui permet de faire valider le formulaire dès la selection d'une image
				$('#up').submit(function() { 
					// inside event callbacks 'this' is the DOM element so we first 
					// wrap it in a jQuery object and then invoke ajaxSubmit 
					$(this).ajaxSubmit(options); 
					// !!! Important !!! 
					// always return false to prevent standard browser submit and page navigation 
					return false; 
				}); 
 
				// A la selection d'une image, on submit automatiquement le formulaire
				$('#file').change(function() {
					$('#up').submit();
				});
			})
 
			// Ajout à l'écran d'une image
			function Ajouter_photo(image){
				var id=image.substr(15,10) //creation d'un id sans "." ni "/" à l'intérieur
				compteur++;
				alert("ajout: "+compteur);
				if (compteur==3){
				$("input#file").hide(); // on cache le champs à partir de 3 images affichées, l'utilisateur ne peut uploader que 3images max.
				}
				// création de la sctructure d'affichage ce qui va donner un truc comme ça <div class="relatif" id="numero_unnique"><div class="absolu"><img src="la/source/" /><img class="delete" id="numero_unique" src=img/delete-icon-small.png></div></div> 
				var divRel = document.createElement("div");
				divRel.setAttribute("class","relatif");
				divRel.setAttribute("id",id);
 
				var divAbs = document.createElement("div");
				divAbs.setAttribute("class","absolu");
 
 
				var img = document.createElement("img");
                img.setAttribute("src",image);
 
				var imgDel = document.createElement("img");
                imgDel.setAttribute("src","img/delete-icon-small.png");
                imgDel.setAttribute("id",id);
				imgDel.setAttribute("class","delete");
 
 
                divRel.appendChild(divAbs);
				divAbs.appendChild(img);
				divAbs.appendChild(imgDel);
				$("#results").append(divRel);
				$(".delete").click(function() { // eventhandler losrque l'on clique sur l'icone delete, on supprime la photo 
					Supprimer_photo(id);
				});
			}
 
			function Supprimer_photo(id){ // cette fonction est appellée plusieurs fois.. sans raison
				alert(id);
				//alert(compteur+" avt");
				$("#"+id+"").fadeOut(function() {
				$("#"+id+"").remove();
				});
				if (compteur==3){
				$("input#file").show();
				}
				compteur--;	
			}
le alert placé dans la fonction de suppression m'indique des id plausibles avant la suppression, mais ces id n'existent pas.. du coup mon compteur est décrémenté quand même et cela fausse tout..

CORRECTION :

Voici le code fonctionnel, le souci venait de la fonction s'occupant de l'envent $(".delete").click(function().. qui n'était pas assez spécifique, l'ajout d'un id unique dans la selection est donc adéquat, comme ceci : $("#"+id+" img").click(function()

Code :
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
<script type="text/javascript">
			var compteur=0;
			$(document).ready(function()
			{   
 
			var options ={
					dataType:  'json', 
					beforeSubmit: function(){
					$('#loader').html('<img src="img/loading.gif" id="waiting">'); // L'animation de chargement
					$('#erreur').remove();
					},
					success:function(data){
 
						$('#waiting').remove(); // on supprime l'animation de chargement
						// Si erreur est set à 1... on annule et on prévient
						if(data.erreur=='1'){
							$('#loader').html('<span id="erreur" class="erreur">'+data.message+'</span>'); // On affiche le message d'erreur dans la div
						}
						// Si l'upload s'est bien passé, on affiche l'image
						else{
							Ajouter_photo(data.image); // ici data.image est le chemin vers mon image
						}
					}
				}
				// fonction qui permet de faire valider le formulaire dès la selection d'une image
				$('#up').submit(function() { 
					// inside event callbacks 'this' is the DOM element so we first 
					// wrap it in a jQuery object and then invoke ajaxSubmit 
					$(this).ajaxSubmit(options); 
					// !!! Important !!! 
					// always return false to prevent standard browser submit and page navigation 
					return false; 
				}); 
 
				// A la selection d'une image, on submit automatiquement le formulaire
				$('#file').change(function() {
					$('#up').submit();
				});
			})
 
			// Ajout à l'écran d'une image
			function Ajouter_photo(image){
				var id=image.substr(15,10) //creation d'un id sans "." ni "/" à l'intérieur
				compteur++;
				//alert("ajout: "+compteur);
				if (compteur==3){
				$("input#file").hide(); // on cache le champs à partir de 3 images affichées, l'utilisateur ne peut uploader que 3images max.
				}
				// création de la sctructure d'affichage ce qui va donner un truc comme ça <div class="relatif" id="numero_unnique"><div class="absolu"><img src="la/source/" /><img class="delete" id="numero_unique" src=img/delete-icon-small.png></div></div> 
				var divRel = document.createElement("div");
				divRel.setAttribute("class","relatif");
				divRel.setAttribute("id",id);
 
				var divAbs = document.createElement("div");
				divAbs.setAttribute("class","absolu");
 
 
				var img = document.createElement("img");
                img.setAttribute("src",image);
 
				var imgDel = document.createElement("img");
                imgDel.setAttribute("src","img/delete-icon-small.png");
                imgDel.setAttribute("id",id);
				imgDel.setAttribute("class","delete");
 
 
                divRel.appendChild(divAbs);
				divAbs.appendChild(img);
				divAbs.appendChild(imgDel);
				$("#results").append(divRel);
				$("#"+id+" img").click(function() { // eventhandler losrque l'on clique sur l'icone delete, on supprime la photo 
					Supprimer_photo(id);
				});
			}
 
			function Supprimer_photo(id){ // cette fonction est appellée plusieurs fois.. sans raison
				//alert(id);
				//alert(compteur+" avt");
				$("div#"+id+"").fadeOut(function() {
				$("div#"+id+"").remove();
				});
				if (compteur==3){
				$("input#file").show();
				}
				compteur--;	
			}
		</script>
titimoi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/01/2012, 23h07   #2
Membre habitué
 
Homme eric
Étudiant
Inscription : décembre 2010
Messages : 103
Détails du profil
Informations personnelles :
Nom : Homme eric

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : décembre 2010
Messages : 103
Points : 100
Points : 100
Bonjour,

pour moi ton code va bien, il n'execute supprimer image qu'une fois, lorsque l'icone de suppression est cliquée.

par contre, comme l'icone de suppression est sur l'image, l'évènement associé au clique sur l'image est aussi déclenché, pour moi ca fait apparaitre une nouvelle image (la meme) à la suite.

je ne sais pas si je t'ai aidé, mais j'ai observé ce que donne ton code en testant juste ca dans une page vierge , et le body qui porte l'id results

Code :
1
2
3
4
 
$(document).click(function(){
  Ajouter_photo('https://calendar.google.com/googlecalendar/images/calendar_logo_vr.png');            
            });
utopman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/01/2012, 23h25   #3
Rédacteur
 
Avatar de danielhagnoul
 
Homme Daniel Hagnoul
Étudiant perpétuel
Inscription : février 2009
Messages : 3 221
Détails du profil
Informations personnelles :
Nom : Homme Daniel Hagnoul
Âge : 61
Localisation : Belgique

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

Informations forums :
Inscription : février 2009
Messages : 3 221
Points : 6 767
Points : 6 767
Bonsoir

Code :
1
2
3
4
$(".delete").click(function() {
   Supprimer_photo(id);
   return false;
});
__________________

FAQ jQuery

Mon cahier d’exercices sur jQuery & Co

Si un message vous a aidé ou vous semble pertinent, votez pour lui !
danielhagnoul est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 22/01/2012, 23h27   #4
Candidat au titre de Membre du Club
 
Inscription : août 2008
Messages : 66
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 66
Points : 11
Points : 11
Bonsoir,
Merci à tous les deux. Le souci venait en fait du handler qui était associé à de nombreuses balises, j'ai rajouté une dépendance à l'id :

Code :
$("#"+id+" img").click(function() {...
Merci encore
titimoi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/01/2012, 00h42   #5
Candidat au titre de Membre du Club
 
Inscription : août 2008
Messages : 66
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 66
Points : 11
Points : 11
danielhagnoul je m'aperçois que j'avais répondu à côté, le return false; il est indispensable? car je lis énormément de code qui n'a jamais de return false.. ?

Une autre question, a priori on essaye d'éviter le plus possible les variables globales, ici mon compteur, il y a une technique pour éviter cela ? (je lisais dans ton cahier d'exercice les clôtures, ça peut servir pour ça ?)
titimoi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2012, 01h37   #6
Rédacteur
 
Avatar de danielhagnoul
 
Homme Daniel Hagnoul
Étudiant perpétuel
Inscription : février 2009
Messages : 3 221
Détails du profil
Informations personnelles :
Nom : Homme Daniel Hagnoul
Âge : 61
Localisation : Belgique

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

Informations forums :
Inscription : février 2009
Messages : 3 221
Points : 6 767
Points : 6 767
Bonsoir

Le return false évite l'action par défaut et la propagation des événements. La clôture permet de travailler dans un espace clos, mais je n'ai pas assez de temps pour voir si c'est utile pour votre code.

Par contre, il ne faut jamais déclarer des gestionnaires d'événements dans une fonction qui sera appelée plus d'une fois, car vous créez autant de fois l'événement que vous appelez la fonction. C'est sans doute l'origine de votre problème pour la suppression.
__________________

FAQ jQuery

Mon cahier d’exercices sur jQuery & Co

Si un message vous a aidé ou vous semble pertinent, votez pour lui !
danielhagnoul est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2012, 01h41   #7
Candidat au titre de Membre du Club
 
Inscription : août 2008
Messages : 66
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 66
Points : 11
Points : 11
Citation:
Par contre, il ne faut jamais déclarer des gestionnaires d'événements dans une fonction qui sera appelée plus d'une fois, car vous créez autant de fois l'événement que vous appelez la fonction. C'est sans doute l'origine de votre problème pour la suppression.
C'est une très bonne remarque, sauf qu'ici j'en ai eu besoin, car à l'ajout d'une image, j'ajoute un évènement propre à cette image. Le tout est de bien faire attention à ce que l'évènement ne soit créé QUE pour cette image, d'où mes id (créés à partir d'un md5(rand())) en php qui sur 3 photos peuvent être considérés comme uniques.)
titimoi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2012, 02h07   #8
Rédacteur
 
Avatar de danielhagnoul
 
Homme Daniel Hagnoul
Étudiant perpétuel
Inscription : février 2009
Messages : 3 221
Détails du profil
Informations personnelles :
Nom : Homme Daniel Hagnoul
Âge : 61
Localisation : Belgique

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

Informations forums :
Inscription : février 2009
Messages : 3 221
Points : 6 767
Points : 6 767
Un gestionnaire d'événement $(".delete").click(function() { ... }); est créé chaque fois que vous appelez la fonction Ajouter_photo et il n'est pas spécifique à une photo.

Petit code de test :

Code :
1
2
3
4
5
6
7
8
9
10
11
var testClick = function(){
	$( "section.conteneur" ).click( function(){
		console.log( "clic sur la section conteneur" );
	});
};
 
for (var i = 0; i < 10; i++ ){
	testClick();
}
 
$( "section.conteneur" ).click();
Et je trouve dans la console de Firebug, dix fois :

clic sur la section conteneur        new-qr1.html (ligne 69)
Hors transaction AJAX, vous pouvez mettre au point un test similaire pour votre code. Je crains qu'il ne faille revoir la logique de votre construction.
__________________

FAQ jQuery

Mon cahier d’exercices sur jQuery & Co

Si un message vous a aidé ou vous semble pertinent, votez pour lui !
danielhagnoul est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2012, 02h10   #9
Candidat au titre de Membre du Club
 
Inscription : août 2008
Messages : 66
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 66
Points : 11
Points : 11
Je répète que ma fonction a été corrigée par rapport au premier post :
Code :
$("#"+id+" img").click(function()..
C'est donc bel et bien spécifique. Je vais updater mon premier post pour être plus clair
titimoi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2012, 02h18   #10
Rédacteur
 
Avatar de danielhagnoul
 
Homme Daniel Hagnoul
Étudiant perpétuel
Inscription : février 2009
Messages : 3 221
Détails du profil
Informations personnelles :
Nom : Homme Daniel Hagnoul
Âge : 61
Localisation : Belgique

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

Informations forums :
Inscription : février 2009
Messages : 3 221
Points : 6 767
Points : 6 767
Ha ! Je n'avais pas vu

Mais je vais laisser le message, il servira sans doute encore dans le futur.
__________________

FAQ jQuery

Mon cahier d’exercices sur jQuery & Co

Si un message vous a aidé ou vous semble pertinent, votez pour lui !
danielhagnoul est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 16h41.


 
 
 
 
Partenaires

Hébergement Web