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 :

Ma fonction ne veut pas retourner un élément


Sujet :

JavaScript

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 31
    Points : 23
    Points
    23
    Par défaut Ma fonction ne veut pas retourner un élément
    Bonsoir à tous,

    Je viens de m'inscrire à ce forum parce que je rencontre un problème vraiment étrange, et je pense que d'autres se sont probablement déjà confronté à ce type d'anomalies.

    Je cherche à faire une fonction JS qui parcourt récursivement les éléments parents de l'élément passé en premier argument, jusqu'à ce qu'on trouve un élément parent qui réponde aux caractéristiques définies dans l'objet passé en second argument de la fonction.

    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function getParent(el, Identificateur) {
    	for (var type in Identificateur) var bool = (el.parentNode[type] ? (el.parentNode[type] == Identificateur[type]) : false);
    	if(!bool) getParent(el.parentNode, Identificateur);
    	else return el.parentNode;
    }
    Ensuite il me reste à l'appeler, voici un exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function test(el) {
    	var it = getParent(el, { className:"item" });
    	alert(it.id);
    }
    <div class="item" id="item1">
    	<div><p><span><a href="#" onclick="test(this);">test link</a></span></p></div>
    </div>
    Normalement, ce code devrait afficher une alerte JS "item1", puisque je lui demande d'afficher l'id de l'élément parent de l'élément "a" dont la classe est définie à "item".
    Eh bien ce n'est pas le cas.

    Et pourtant, si au lieu de retourner l'élément parent, je le manipule dans la fonction, cela fonctionne... Ainsi le code suivant affiche bien une alerte "item1" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function getParent(el, Identificateur) {
    	for (var type in Identificateur) var bool = (el.parentNode[type] ? (el.parentNode[type] == Identificateur[type]) : false);
    	if(!bool) getParent(el.parentNode, Identificateur);
    	else alert(el.parentNode.id);
    }
    function test(el) {
    	getParent(el, { className:"item" });
    }
    <div class="item" id="item1">
    	<div><p><span><a href="#" onclick="test(this);">test link</a></span></p></div>
    </div>
    La seule chose qui ait changé, c'est que je ne retourne plus l'élément, mais je le manipule dans la fonction en alertant la valeur de son id.
    Ce que je ne comprends pas, c'est pourquoi je ne peux pas retourner cet élément, pour le manipuler en dehors de la fonction.

    Si vous avez des idées pour me sortir de cette impasse, je suis preneur, parce que cela fait deux heures que je m'arrache les cheveux sur trois malheureuses lignes de code.... à devenir fou

    Merci d'avance !

  2. #2
    Expert confirmé
    Avatar de emmanuel.remy
    Inscrit en
    Novembre 2005
    Messages
    2 855
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 855
    Points : 4 045
    Points
    4 045
    Par défaut Recursivité
    Salut,

    Ta fonction ne retourne aucune valeur en cas de récursivité.
    Et il faut faire un break dès qu'on a trouvé une concordance.

    Finalement ceci devrait faire l'affaire (à ajuster selon tes besoins):
    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
     
      <script type="text/javascript">
        function getParent(el, Identificateur) {
        	var bool;
        	var res;
     
        	for (var type in Identificateur)  {
            	bool = (el.parentNode[type] ? (el.parentNode[type] == Identificateur[type]) : false);
            	if (bool) break;
        	}
     
          if (!bool) { 
            //a t on encore des parents à parcourir ?
          	if (el.parentNode.parentNode) {
          		return getParent(el.parentNode, Identificateur);
          	} else {
          		return null;
          	}
          } else { 
          	return el.parentNode;
          }
        }  
     
      function test(el) {
      	var it = getParent(el, { className:"item" }) ;
      	alert(it ? it.id :"Pas de résultat");
      }
      </script>
     
    <div class="item" id="item1">
    	<div><p><span><a href="#" onclick="test(this);">test link</a></span></p></div>
    </div>
    ERE

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 31
    Points : 23
    Points
    23
    Par défaut
    Salut !

    Merci pour ta réponse, c'est effectivement lié à la récursivité de la fonction.

    Le problème avec le break, c'est que dés qu'il trouve une condition remplie il s'arrête, or je voudrais pouvoir passer plusieurs paramètres à vérifier dans l'objet Identificateur.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var elem = getParent(el, { className:"item", tagName:"div", id:"item1" })
    J'ai essayé avec
    Mais dans ce cas il affiche "pas de résultat". Une idée pour appliquer les différents contrôles contenus dans l'objet ?

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 31
    Points : 23
    Points
    23
    Par défaut
    personne n'a une idée pour me tirer de là ?

  5. #5
    Expert confirmé
    Avatar de emmanuel.remy
    Inscrit en
    Novembre 2005
    Messages
    2 855
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 855
    Points : 4 045
    Points
    4 045
    Par défaut
    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
     
    	  <script type="text/javascript">
    	    function getParent(el, Identificateur) {
                   //on considère que c'est bon...                
    	    	var bool = true;
    	    	var res;
     
    	    	for (var type in Identificateur)  {
                           //on cumule le resultat des évaluation              s
                           bool = bool && (el.parentNode[type] ? (el.parentNode[type] == Identificateur[type]) : false);
                           //si à un moment on est dans les choux on quitte ;)
    	        	if (!bool) break;
    	    	}
     
    	      if (!bool) { 
    	      	if (el.parentNode.parentNode) {
    	      		return getParent(el.parentNode, Identificateur);
    	      	} else {
    	      		return null;
    	      	}
    	      } else { 
    	      	return el.parentNode;
    	      }
    	    }  
     
          function test(el) {
              var it = getParent(el, { className:"item" ,tagName: "DIV", id:"item1"}) ;
              alert(it ? it.id :"Pas de résultat");
     
              it = getParent(el, { className:"item" ,tagName: "DIV", id:"item2"}) ;
              alert(it ? it.id :"Pas de résultat");
     
              it = getParent(el, { className:"item1" ,tagName: "DIV", id:"item1"}) ; 
              alert(it ? it.id :"Pas de résultat");
          }
    	  </script>
     
      	<div class="item" id="item1" >
      		<div><p><span><a href="#" onclick="test(this);">test link</a></span></p></div>
      	</div>
    ok pour toi ?

    ERE

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 31
    Points : 23
    Points
    23
    Par défaut
    Mais bien sûr, c'est ça !
    J'ai un peu honte sur ce coup-là, il suffisait de breaker si bool était false...
    Comme quoi, quand on a trop le nez dedans, c'est bon d'avoir un regard extérieur.
    Merci beaucoup de ta patience et de ton aide précieuse

  7. #7
    Expert confirmé
    Avatar de emmanuel.remy
    Inscrit en
    Novembre 2005
    Messages
    2 855
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 855
    Points : 4 045
    Points
    4 045
    Par défaut
    Citation Envoyé par razbitume Voir le message
    Mais bien sûr, c'est ça !
    J'ai un peu honte sur ce coup-là, il suffisait de breaker si bool était false...
    Comme quoi, quand on a trop le nez dedans, c'est bon d'avoir un regard extérieur.
    Merci beaucoup de ta patience et de ton aide précieuse
    Il fallait aussi cumuler les bool pour traiter toutes les attributs de Identificateur

    Bon dev,

    ERE

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 31
    Points : 23
    Points
    23
    Par défaut
    Merci encore pour ton aide.
    Cela dit j'ai fait des tests concluants sans être obligé de cumuler l'ancienne et la nouvelle valeur de bool, puisque de toute façon il break dès qu'une condition n'est pas remplie.
    La fonction marche très bien comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function getParent(el, Identificateur) {            
    	var bool = true;
    	for (var type in Identificateur)  {
    			   bool = (el.parentNode[type] ? (el.parentNode[type] == Identificateur[type]) : false);
    		if (!bool) break;
    	}
    	if (!bool) { 
    		if (el.parentNode.parentNode) return getParent(el.parentNode, Identificateur);
    		else return null;
    	} else return el.parentNode;
    }
    A bientôt, bons devs à toi aussi !

  9. #9
    Expert confirmé
    Avatar de emmanuel.remy
    Inscrit en
    Novembre 2005
    Messages
    2 855
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 855
    Points : 4 045
    Points
    4 045
    Par défaut
    Oups, désolé pour cette erreur

    Je ne sais pas ce que j'ai fait avec ce cumul de variable bool, parce que là c'est énorme !


    ERE

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 05/06/2009, 12h18
  2. Une fonction qui ne veut pas de mes variables
    Par zebulondu54 dans le forum Langage
    Réponses: 5
    Dernier message: 09/06/2008, 05h41
  3. Une fonction virtuelle ne peut pas retourner un template!
    Par coyotte507 dans le forum Langage
    Réponses: 10
    Dernier message: 08/02/2008, 20h39
  4. Réponses: 3
    Dernier message: 29/01/2008, 16h17
  5. Réponses: 1
    Dernier message: 17/10/2007, 10h04

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