11550 sujets

JavaScript, DOM et API Web HTML5

Pages :
(reprise du message précédent)

Julien Royer a écrit :

Pour conserver l'objet de l'arbre DOM correspondant à l'élément input, il aurait fallu écrire var cur = this;.


Désolé mais cela est faux et provoque une erreur jquery et un arrêt du script.

Extrait de firebug si l'on applique la correction recommandée :

cur.attr is not a function

Pour vérifier et reproduire l'erreur il vous suffit de modifier ma proposition d'exemple fonctionnel.
Julien de Prabere a écrit :

success : function(msg){

	c='';for (i in cur) c+=' '+i+' val '+cur[ i];
	alert('cur.name '+cur.name+' cur.id '+cur.id+' autre p. et v. : '+c)

  	if (msg == 1) {cur.attr("value","actif"+cur.attr("id"));} 
	else {cur.attr("value","inactif"+cur.attr("id"));}}
});


l'alert donne ça :

cur.name undefined cur.id undefined autre p. et v. :  0 val
 [object HTMLInputElement] length val 1

Tout ce que l'on constate c'est que la propriété .name et .id ne sont pas défini pour l'objet courant à l'index courant; ce qui est normal puisque la fonction $('qqchose') retourne un jeu de résultats sous forme d'objet jquery ; pour avoir le nom d'un element on doit utiliser par exemple
var myTag = $('qqchose').get(0).tagName ou $('qqchose') [0] en raccourci... 
PiR2 a écrit :
bin proposer un exemple fonctionnel complet (même imparfait) au demandeur initial puisque personne ne l'a fait... Smiley ohwell

L'exemple que j'ai fourni était jusqu'à preuve du contraire complet. Le problème de départ était juste que this ne ciblait pas le bon objet (problème malheureusement courant en JavaScript).

Quant à ta réponse, data: "id=" + $(this).attr("name") est totalement inutile. Je pense que tu mélanges les objets correspondant au bouton et à la requête AJAX.
PiR2 a écrit :
Désolé mais cela est faux et provoque une erreur jquery et un arrêt du script.

Qu'est-ce qui est faux exactement ? Décidément, ne pas lire avec attention les réponses précédentes semble devenir une habitude. Smiley cligne
Julien Royer a écrit :

L'exemple que j'ai fourni était jusqu'à preuve du contraire complet. Le problème de départ était juste que this ne ciblait pas le bon objet (problème malheureusement courant en JavaScript).


D'accord avec toi sur le fait que ton exemple est fonctionnel si l'on emploi un élément autre qu'un bouton de type input; or pour ma part j'ai compris que la demande initiale porte sur des boutons. Ton code appliqué à un bouton de type input ne fonctionne pas.

Julien Royer a écrit :

Quant à ta réponse, data: "id=" + $(this).attr("name") est totalement inutile. Je pense que tu mélanges les objets correspondant au bouton et à la requête AJAX.


Bin non justement, cela s'applique au cas bouton de type input, dans ce cas le "texte" du bouton change, je me suis tjrs placé dans ce cadre.
Julien Royer a écrit :

Qu'est-ce qui est faux exactement ? Décidément, ne pas lire avec attention les réponses précédentes semble devenir une habitude. Smiley cligne


Je te cite :

Julien Royer a écrit :

Pour conserver l'objet de l'arbre DOM correspondant à l'élément input, il aurait fallu écrire var cur = this;


Si l'on injecte cette ligne directement dans le script jquery cela provoque l'erreur évoquée ds firebug.
J'essaye juste d'être constructif et d'apporter des réponses (modestes), n'y voit aucun mal !!
Smiley biggol
PiR2 a écrit :
D'accord avec toi sur le fait que ton exemple est fonctionnel si l'on emploi un élément autre qu'un bouton de type input; or pour ma part j'ai compris que la demande initiale porte sur des boutons. Ton code appliqué à un bouton de type input ne fonctionne pas.

Admettons, même s'il me semblait plutôt clair que le problème ne portait pas là-dessus :
a écrit :
Je comptais sur le "this" mais vu qu'il est dans une fontion, il ne trouve plus mon ".promo"

PiR2 a écrit :
Si l'on injecte cette ligne directement dans le script jquery cela provoque l'erreur évoquée ds firebug.
J'essaye juste d'être constructif et d'apporter des réponses (modestes), n'y voit aucun mal !!
Smiley biggol

Ce n'est justement pas très constructif puisque tu sors ma réponse de son contexte et que tu es assez catégorique ("Désolé mais cela est faux"). Je précisais juste à Julien que l'objet cur était en effet un objet JQuery, et que si l'on voulait obtenir l'objet de l'arbre DOM, il fallait écrire "cur = this". C'est d'ailleurs ce que tu as dit dans ta réponse suivante.

Enfin bref, n'en faisons pas un mélodrame, je préfère juste que les choses soient claires. Smiley smile
Julien Royer a écrit :

Ce n'est justement pas très constructif puisque tu sors ma réponse de son contexte et que tu es assez catégorique ("Désolé mais cela est faux").


En fait c'est une mauvaise interprétation de ma part de ta réponse, je ne l'avais pas lu comme ça au départ... quote un peu rapide à la réflexion, je me flagelle 10 fois ce soir !!
Smiley biggrin

Pas tjrs facile de se comprendre par forum interposé... On ne visait pas le même objectif de réponse et solution.
Modifié par PiR2 (17 Mar 2009 - 16:38)
Un script établit sur le schéma suivant (moins de 2ko tout compris sans jQuery) me semble pouvoir, en toute hypothèse, être beaucoup plus performant que tous vos développements.

function sndRqu(url,cllbck,pstDta){
	var req=xmlObj();
	if (!req) return;
	var mth=(pstDta)? "POST":"GET";
	req.open(mth,url,true);
	req.setRequestHeader('User-Agent','XMLHTTP/1.0');
	if (pstDta) req.setRequestHeader(
		'Content-type','application/x-www-form-urlencoded');
	req.onreadystatechange=function(){
		if (req.readyState!=4) return;
		if (req.status!=200 && req.status!=304) return;
		cllbck(req);}
	if (req.readyState==4) return;
	req.send(pstDta);
};
var xmlFct=[function(){return new XMLHttpRequest()},
	function(){return new ActiveXObject("Msxml2.XMLHTTP")},
	function(){return new ActiveXObject("Msxml3.XMLHTTP")}];
function xmlObj(){
	var xmlhttp=false;
	for (var i=0;i<xmlFct.length;i++) {
		try{xmlhttp = xmlFct[ i]();}
		catch(e){continue;}
		break;}
	return xmlhttp;
};
function $(i){return document.getElementById(i)}
function init(){var i,t=document.getElementsByTagName('input');
   for (i in t) 
		if (/test/.test(t[ i].className)) t[ i].onclick=clc;
}
function clc(e){var t=e?e.target:window.event.srcElement;
	sndRqu("ajax.php?id="+t.id+"&vl="+t.value,
		function(r){var w=r.responseText;
			if (w) $(w.substr(0,3)).value=w.substr(3);})
}
window.onload=init;


Assortit des boutons ci-après (les attributs names inutiles pour la démonstration ont été supprimés)

<input type="button" id="ib1" value="non pub" class="test" /> <br />
<input type="button" id="ib2" value="non pub" class="test" /> <br />
<input type="button" id="ib3" value="non pub" class="test" /> <br />
<input type="button" id="ib4" value="autre" class="test" /> <br />

et, pour l'exemple, d'un fichier ajax.php retournant simplement l'identifiant et la nouvelle valeur du bouton :

if (!empty($_GET["id"]) && !empty($_GET["vl"])) {
	if ($_GET["vl"]=="non pub") exit($_GET["id"]."pub");
	if ($_GET["vl"]=="pub") exit($_GET["id"]."non pub");}
exit();

il devrait répondre à la question posée, sans encombrer inutilement la mémoire du poste client.

Accessoirement les modérateurs simplement intéressés vérifieront aisément qu'une variable, déclarée locale dans la fonction lancée lors du clic sur un bouton, ne sera en général plus disponible dans la fonction de callback de la requête correspondante.
Modifié par Julien de Prabere (17 Mar 2009 - 17:26)
Le sujet est résolu, donc il n'est sans doute pas nécessaire de chercher des solutions à un problème inexistant (même si j'ai moi-même ma part de responsabilité, je le reconnais Smiley cligne ).
Julien de Prabere a écrit :
Accessoirement les modérateurs simplement intéressés vérifieront aisément qu'une variable, déclarée locale dans la fonction lancée lors du clic sur un bouton, ne sera en général plus disponible dans la fonction de callback de la requête correspondante.

Il s'agit du mécanisme de fermeture (closure) déjà évoqué plus haut dans le sujet. Je t'invite à te documenter à ce sujet et éventuellement à ouvrir un nouveau sujet si tu n'es pas d'accord et que tu veux en discuter. Petit exemple succins et classique :
function makeAdder(a) {
  return function(b) {
    return a + b;
  };
}

var add2 = makeAdder(2), add3 = makeAdder(3);

alert add2(1); // 3
alert add3(1); // 4
Merci pour ces précisions sur cette intéressante question.

On aurait simplement pu craindre, ne voyant aucune déclaration de variable locale dans cette fonction, qu'elle fût évoquée pour noyer le poisson.
Modifié par Julien de Prabere (17 Mar 2009 - 18:22)
Julien de Prabere a écrit :
On aurait simplement pu craindre, ne voyant aucune déclaration de variable locale dans cette fonction, qu'elle fût évoquée pour noyer le poisson.

Une variable locale a exactement la même portée qu'un paramètre (tu aurais d'ailleurs pu le constater si tu avais fait l'effort de le tester toi même).

P.S. : tu manipule visiblement bien le sarcasme, mais celui-ci est en général assez ridicule sans une bonne maîtrise du sujet.
Je ferme le sujet, car l'on s'égare de plus en plus de la question d'origine. Merci de créer un nouveau sujet si nécessaire (comme déjà indiqué).
Pages :