Invité Posté 24 Janvier 2010 Posté 24 Janvier 2010 Bonsoir à tous, il y a quelque chose que je ne comprends pas sur la façon dont Javascript traite les objets passés dans les fonctions et je ne trouve pas de doc... J'ai plusieurs fonctions qui font ça en gros : function fonc_1(obj){ fonc_2(obj); } function fonc_2(obj){ setTimeout("alert(obj.src); obj.src = 'truc.jpg'", 5); } Donc si ma première image de la page est machin.jpg et que je fais fonc1(document.images[0]); j'obtiens le message "machin.jpg" et machin.jpg est transformé en truc.jpg au bout de 5 secondes. Tout va bien. Par contre, si pendant l'intervalle des 5 secondes j'ai le malheur d'appeler la fonction de nouveau (par exemple fonc1(document.images[1])), au bout des 5 secondes j'obtiens le message "machin.jpg" mais machin.jpg n'est plus transformé en truc.jpg. Tout se passe comme si l'objet et ses propriétés étaient bien définis au moment de l'éxécution du Timeout, mais que le Javacript s'était emmêlé les pinceaux et ne retrouve plus l'objet dans la page. J'ai tenté des tas de choses pendant 24h, je n'en peux plus là... Merci !
SStephane Posté 24 Janvier 2010 Posté 24 Janvier 2010 Hello, on peut voir la source entière dans une page ? c'est plus facile pour utiliser un débogueur (et te répondre) qu'un fragment de code. D'instinct comme ça je n'ai qu'une question, à quoi sert fonc_1 ?
Invité Posté 24 Janvier 2010 Posté 24 Janvier 2010 Bonsoir SStephane et merci, ma fonction 1 (--> details) regarde si telle balise img existe déjà dans la page. Si ce n'est pas le cas, elle la crée et appelle la fonction 2 (--> qz_grayscale_test) en la lui passant en argument : var dzidx = 1; function details(creation_id){ logo = document.getElementById("im_"+creation_id); if(!logo){ di = document.getElementById("demoimg_"); di.innerHTML += "<img id=\"im_\"+creation_id+"" src=\"image_"+creation_id+".jpg\"/>"; logo = document.getElementById("im_"+creation_id); qz_grayscale_test(logo); } //put the current logo on top of the others logo.style.zIndex = dzidx; dzidx++; } Remarque: j'ai un peu simplifié les trucs pas importants, j'espère ne pas avoir laissé de petite incohérence La deuxième fonction regarde juste si l'image correspond à une valeur enregistrée dans un cookie et la passe à une troisième fonction si c'est le cas : function qz_grayscale_test(obj){ //see into the cookie if the logo should be black and white gs = obj.src; if(gs){ gs = gs.replace(/.*\\/images\\/([a-z]+)\\/[0-9]+\\/([0-9]+)\\/logo.jpg$/g, "$1:$2"); gs = gs.split(":"); if(gs[0]=="quiz") gs[0]=1; if(gs[0]=="test") gs[0]=2; if(gs[0]=="poll") gs[0]=3; gt = qz_cookie_read("qzci_"+gs[0]); if(gt) { gt = gt.split(":"); for(gti in gt){ //if we find it the cookie values if(gt[gti] === gs[1]){ qz_grayscale(obj); } } } } } la fonction 3 (--> qz_grayscale) crée un double de l'image et passe le relais à la fonction 4 (sous Firefox) qui s'exécutera quand ce double sera chargé (.onload) : //transform a picture into a black & white version (grayscaling) function qz_grayscale(oImg){ if(!oImg.grayscaled){ oImg.grayscaled = true; if(IE){ oImg.style.filter = "progid:DXImageTransform.Microsoft.BasicImage(grayScale=1)"; } else{ oImg.cloneImg = new Image; oImg.cloneImg.onload = function(){ qz_grayscale2(oImg); }; oImg.cloneImg.src = oImg.src; } } } pour finir, la fonction 4 calcule la version noir et blanc du double et doit la mettre dans l'attribut src de l'image d'origine : function qz_grayscale2(oImg){ var canvas = document.createElement("canvas"); var canvasContext = canvas.getContext("2d"); imgW = oImg.cloneImg.width; imgH = oImg.cloneImg.height; canvas.width = imgW; canvas.height = imgH; canvasContext.drawImage(oImg.cloneImg, 0, 0); var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH); for(y = 0; y < imgPixels.height; y++){ for(x = 0; x < imgPixels.width; x++){ i = (y * 4) * imgPixels.width + x * 4; avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3; imgPixels.data[i] = avg; imgPixels.data[i + 1] = avg; imgPixels.data[i + 2] = avg; } } canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height); oImg.src = canvas.toDataURL(); } Mais je répète que ça foire **uniquement** quand les fonctions sont re-appelées avant que le onload qui déclenche la 4ème fonction se déclenche. Le timeout que j'ai évoqué avant m'a permis d'agrandir le délai avant l'éxécution de ce onload et constater que c'était bien ce laps de temps qui pose problème. Dernière chose : dans la 4ème fonction, la preuve qu'il connait l'objet sans pouvoir y accéder directement (uniquement quand les fonctions ont été rappelées) pour lui assigner une nouvelle src, c'est que si je remplace ceci : oImg.src = canvas.toDataURL(); par cela : document.getElementById(oImg.id).src = canvas.toDataURL(); là ça fonctionne bien ! Même un alert(oImg.src) dans la 4è fonction me renvoie toujours la valeur actuelle de src (donc ça marche pour "lire") alors que oImg.src = canvas.toDataURL() juste après ne fonctionne pas (donc ça foire pour "écrire"). Alors soit vous me dites que je n'ai pas tout compris au fonctionnement des objets dans les fonctions, soit vous me dites que c'est une histoire de fous et je vous fais une URL pour tester par vous-mêmes
SStephane Posté 24 Janvier 2010 Posté 24 Janvier 2010 En fait je voulais dire une page en ligne, que je puisse répondre rapidement (si j'en suis capable ), le débogueur me permettrait de poser des points arrêt pour parcourir les objets et tout le reste, ça reste très abstrait. Je te fais donc une réponse rapide sans examiner plus le truc. oImg.cloneImg.onload = function(){ qz_grayscale2(oImg); }; Cette manière de procéder est foireuse, car le oImg passe à moitiée et je trouve ça déjà surprenant, car elle n'est pas sensé passer dans un langage objet normal, onload attend un délégué. Le fait de le déclarer directement (la partie : function(){ qz_grayscale2(oImg); } devrait créer normalement un nouveau contexte, je trouverai ça logique, d'ailleurs en Java, je pense que tu te fais sanctionner. Je veux bien une url, j'ai une bonne idée d'où vient ton souci.
Invité Posté 25 Janvier 2010 Posté 25 Janvier 2010 Bonsoir ! Voilà je n'ai pas eu le temps de la faire aujourd'hui mais ça y est : />http://quizity.com/webhub/test.html Si tu appuies sur le bouton 2 avant que l'image 1 soit en noir et blanc, ça l'empêchera de fonctionner. Merci !
SStephane Posté 26 Janvier 2010 Posté 26 Janvier 2010 function details(creation_id){ logo = document.getElementById(creation_id); if(!logo){ src = "./image/"+creation_id+".jpg"; var img = document.createElement('IMG'); img.setAttribute('id',creation_id); img.setAttribute('src',src); di = document.getElementById("demoimg"); di.appendChild(img); var logo = document.getElementById(creation_id); //test the creation to know if it has been played and if the logo should be grayscaled qz_grayscale_test(logo); }} Tu comprendras aisément ton erreur Par ailleurs je comprends mal ta manière de faire à certains endroits
Invité Posté 26 Janvier 2010 Posté 26 Janvier 2010 Extraordinaire ! on dirait que tu as trouvé sans forcer en plus, bravo ! Je ne sais pas comment te remercier je vais devoir faire des modifs dans plusieurs de mes pages pour m'adapter à ce que tu as trouvé Je ne sais pas ce que tu trouves bizarre, j'ai essayé de rester simple et logique pourtant ? Si c'est le fait de cloner l'image qui te trouble, en fait je fais ça pour avoir la véritable taille de l'image et non celle qui lui est donnée par CSS (offsetheight me renvoie aussi cette taille CSS). Merci encore!
SStephane Posté 27 Janvier 2010 Posté 27 Janvier 2010 Je veux dire que tu as beaucoup de variables globales qui sont en fait locales, la fonction 2 (dont je ne me souviens plus le nom, ne sert effectivement à rien). Sinon pour trouver rapidement, je n'ai pas grand mérite, dis merci à firebug
Invité Posté 27 Janvier 2010 Posté 27 Janvier 2010 Ha mais ça c'est parce que j'ai simplifié le code, toutes ces choses ont une utilité en réalité
Sujets conseillés
Veuillez vous connecter pour commenter
Vous pourrez laisser un commentaire après vous êtes connecté.
Connectez-vous maintenant