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 :

Pointeur this et événement OnClick


Sujet :

JavaScript

  1. #1
    Membre habitué

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2002
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2002
    Messages : 207
    Points : 133
    Points
    133
    Par défaut Pointeur this et événement OnClick
    Salut tous le monde.

    J'ai besoin de votre aide. Je me met à la POO en JS et j'ai un petit soucis, je m'explique. Je crée une instance de ma classe au début de la page. Ensuite, au clique sur un lien j'appelle 2 fonctions de cette instance, sans soucis tout fonctionne.
    Par contre dans ma fonction ScreenImage, j'associe la fonction CloseGalery de l'objet courant (this) à un lien. A l'usage quand je clique sur ce lien, la fonction CloseGalery est belle-et bien lancé mais this ne pointe pas sur mon instance de classe, mais sur ma page. Du coup tout les attributs (ceux définit das ma ImageGalery tel que CurrentImageIndex ) que je souhaite utiliser dans CloseGalery son undefined


    Je précise que le code ci-dessous, est totalement épuré. L'idée étant de créer une classe qui permettra de gérer un affichage d'image. Je n'ai pas tout mis le code pour alléger le poste et que ça soit plus clair.

    Ma clase ImageGalery

    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
     
    function ImageGalery(p_ImageTable)
      {   
        //Propriété 
        this.ImageTable           = p_ImageTable;   
        this.CurrentImageIndex    = 0;
        this.BackgroundDiv        = null;
     
        this.ScreenBackground = function()
        {
     
        }
     
        this.ScreenImage = function(ImageIndex) 
        {
          this.LinkClose              = document.createElement('A'); 
          this.LinkClose.onclick    =  this.CloseGalery;     
        } 
     
        this.CloseGalery = function()
        {
          alert("this de type  ImageGalery : " + (this instanceof ImageGalery)); // Affiche FALSE 
        }
     
      }

    Code de création de mon instance.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        var ImageList = new Array();
        ImageList[0] = new Array("Upload/aspqvnturspqeft.JPG","Cage Assenseur");
        ImageList[1] = new Array("Upload/bpqewkdajghmfkd.JPG","Maison chintoq");
        ImageList[2] = new Array("Upload/cuijxyvfkdasxqe.JPG","Batiment rond");
        ImageList[3] = new Array("Upload/fklijpqmwclisxh.JPG","Toit");
     
        var MyGalery = new ImageGalery(ImageList);
    L'appelle au 2 fonctions qui fonctionne.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <A href="#" onClick="{MyGalery.ScreenBackground();MyGalery.ScreenImage(0);}"> 
        <IMG src="Upload/aspqvnturspqeft.JPG" width=100px height=100px>
      </A>
    J'espère que vous pourrez m'aidé, j'ai essayé de trouvé ma réponse dans les tuto sur la POO en JS, mais en vain.

    D'avance merci.
    @@++

  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
    Salut,

    Quand tu inscris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.LinkClose.onclick    =  this.CloseGalery;
    JS inscrit une référence à la fonction CloseGalery. Or au moment de l'événement click le this contenu dans CloseGalery fait référence à l'élément qui l'a déclenché, ici ta balise A. Il faut donc garder une référence sur ta class si tu veux éviter cet écueil:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        this.ScreenImage = function(ImageIndex) 
        {
          this.LinkClose              = document.createElement('A'); 
          var self=this;
          this.LinkClose.onclick    =  function () { self.CloseGalery() }; 
        }
    Ainsi quand CloseGalery est appelé il l'est dans le contexte du self, soit la référence de ta class.

    ERE
    Quand une tête pense seule, elle devient folle.

  3. #3
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : Belgique

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

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Points : 22 933
    Points
    22 933
    Billets dans le blog
    125
    Par défaut
    Bonsoir.

    Ce code fonctionne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    this.ScreenImage = function(ImageIndex){
    	this.LinkClose = document.createElement('a'); 
    	var self=this;
    	this.LinkClose.onclick = this.CloseGalery(self);
    } 
     
    this.CloseGalery = function(moi){
    	alert("this de type  ImageGalery : " + (moi instanceof ImageGalery)); // Affiche FALSE 
    }

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  4. #4
    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
    @danielhagnoul: le code fonctionne mais est "anti-POO": pourquoi devoir passer à une fonction d'un objet la référence à cet objet ? Le this est là pour ça.
    Cela n'a de sens que si la fonction devient indépendante de l'objet et nécessite donc d'obtenir une référence à l'objet pour fonctionner correctement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ...
    this.ScreenImage = function(ImageIndex){
    	this.LinkClose = document.createElement('a'); 
    	var self=this;
    	this.LinkClose.onclick = CloseGalery(self);
    } 
    
    //...
    //définit dans le scope de Window		
    var CloseGalery = function(ctx){
    	alert("this de type  ImageGalery : " + (ctx instanceof ImageGalery)); // Affiche FALSE 
    }
    ERE
    Quand une tête pense seule, elle devient folle.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2009
    Messages
    354
    Détails du profil
    Informations personnelles :
    Localisation : France, Sarthe (Pays de la Loire)

    Informations forums :
    Inscription : Février 2009
    Messages : 354
    Points : 491
    Points
    491
    Par défaut
    le js fonctionne comme ça. En js une fonction peut être exécutée dans n'importe qu'elle contexte (ce qui permet une véritable souplesse dans la programmation objet), les références d'une fonction s'applique donc dans le contexte ou on les à référencé.

    Quand un passe une fonction comme un arguments d'une autre, on ne passe qu'une référence, et donc elle s'applique au context de l'instance de Function (qui a créer les arguments et la fonction en elle même), elle même étant global(window).

    Pour référencer une fonction à un objet, on est obligé de référencé le context dans une variable (visible par la fonction)

    (note : les variables dont les fonctions on accès sont celles des contextes de la création de la fonction, ces contextes ne sont pas des objets mais des contextes de fonction, par exemple si je déclare une fonction dans une autre, alors cette dernière aura accès qu'au variable de la fonction qui la crée (récursivement ...), et le context globale window )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
       function mafonctionàliée(){....}
       var context = this;
       var mafonctionliée= function(){
           return  mafonctionàliée.apply(this, arguments);  
       }
    tu peux aussi faire une recherche sur bind en javascript, tu aura pas mal de fonction se basant sur le même principe.

    voilà bye

  6. #6
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : Belgique

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

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Points : 22 933
    Points
    22 933
    Billets dans le blog
    125
    Par défaut
    Bonsoir

    C'était en réaction, un peu trop rapide peut-être , à :

    Citation Envoyé par emmanuel.remy Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        this.ScreenImage = function(ImageIndex) 
        {
          this.LinkClose              = document.createElement('A'); 
          var self=this;
          this.LinkClose.onclick    =  function () { self.CloseGalery() }; 
        }
    ERE
    qui ne fonctionne pas.

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  7. #7
    Membre habitué

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2002
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2002
    Messages : 207
    Points : 133
    Points
    133
    Par défaut
    Merci à tous pour vos réponse, parce que maintenant mon code fonctionne .

    J'aimerais comprendre deux choses :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
       var Self = this;
       this.LinkClose.onclick    = function () { Self.CloseGalery() };
    Je ne vois pas bien pourquoi on doit repréciser le function () {XXXX} pour faire l'assignation. Le type est déjà définit avant lors de la "création" de la fonction.

    Pour ce qui est de l'usage du mot this. Pourquoi ne peut on pas directement assigné la référence de la fonction de cette manière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       this.LinkClose.onclick    = function () { this.CloseGalery() };
    Y a un truc qui m'échappe. Et comme j'aime bien comprendre tout ce que je fais (ce qui énerve un peu ma copine des fois d'ailleurs) je profite encore de votre bonté.
    @@++

  8. #8
    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
    @danielhagnoul: bien sûr que si cela fonctionne ! Va falloir revoir ton javascript !

    Et voilà le code testé (sur une balise P, et pas A, mais cela ne change rien):
    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
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
      <script type='text/javascript' 
            src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
     
     
      <script type="text/javascript">
      function ImageGalery(p_ImageTable)
        {   
          //Propriété 
          this.ImageTable           = p_ImageTable;   
          this.CurrentImageIndex    = 0;
          this.BackgroundDiv        = null;
     
          this.ScreenBackground = function()
          {
     
          }
     
          this.ScreenImage = function(ImageIndex) 
          {
            this.LinkClose = document.createElement('P');
            this.LinkClose.appendChild(document.createTextNode("Cliquez ici !"));
            document.getElementsByTagName("BODY")[0].appendChild(this.LinkClose);
            var self = this;
            this.LinkClose.onclick    =  function () { self.CloseGalery() };     
          } 
     
          this.CloseGalery = function()
          {
            alert("this de type  ImageGalery : " + (this instanceof ImageGalery)); // Affiche FALSE -> plus maintenant !
            console.log(this); 
          }
     
        }
     
      var MyGalery; 
      function addGalery() {
            var ImageList = new Array();
            ImageList[0] = new Array("Upload/aspqvnturspqeft.JPG","Cage Assenseur");
     
            MyGalery = new ImageGalery(ImageList);
            MyGalery.ScreenImage(0);
      }
      </script>
     
      </head>
      <body onload="addGalery();">
     
      </body>
    </html>
    et si tu ne veux pas passer par le self, tu peux aussi écrire (je trouve cela plus compliquer pour un début, mais bon...):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            this.LinkClose.onclick    =  (function (ctx) { return function () { ctx.CloseGalery();};})(this);
    ERE
    Quand une tête pense seule, elle devient folle.

  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
    Citation Envoyé par Seboubou86 Voir le message
    (...)
    Pour ce qui est de l'usage du mot this. Pourquoi ne peut on pas directement assigné la référence de la fonction de cette manière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       this.LinkClose.onclick    = function () { this.CloseGalery() };
    Y a un truc qui m'échappe. Et comme j'aime bien comprendre tout ce que je fais (ce qui énerve un peu ma copine des fois d'ailleurs) je profite encore de votre bonté.
    Le this est résolu lors de l'appel de la fonction, selon le contexte (scope). Donc si tu assignes ainsi la fonction le this vaudra ton LinkClose, soit ton élément qui génère le clic.

    ERE
    Quand une tête pense seule, elle devient folle.

  10. #10
    Membre habitué

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2002
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2002
    Messages : 207
    Points : 133
    Points
    133
    Par défaut
    Ok je comprend mieux l'usage du Self. En gros on recrée une fonction qui appellera la fonction dans l'objet voulut.

    Merci encore pour toutes ces réponses aussi rapides !!!
    @@++

  11. #11
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : Belgique

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

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Points : 22 933
    Points
    22 933
    Billets dans le blog
    125
    Par défaut
    Citation Envoyé par emmanuel.remy Voir le message
    @danielhagnoul: bien sûr que si cela fonctionne ! Va falloir revoir ton javascript !

    ERE
    Aujourd'hui vous avez raison , mais hier rien ne marchait, ni avec Firefox (Firebug me donnait des indications différentes d'aujourd'hui), ni avec Chrome, ni avec IE8 !

    Mais lorsque j'ai éteint mon ordinateur, j'ai eu droit à un dialogue d'alerte : « l'instruction XXX ne peut pas être read » ce qui m'a fortement intrigué et décidé à rejouer la partie aujourd'hui.

    Si ce n'est pas un rayon cosmique qui a perturbé les électrons du CPU, je soupçonne mon logiciel de sécurité qui se met à jour toutes les deux heures.

    Lorsqu'il fonctionne l'ordinateur à tendance à se figer et peut-être cela a-t-il une répercussion sur Firebug.

    En bref, chez moi, ce qui ne marchait absolument pas hier fonctionne aujourd'hui ! C'est inquiétant !

    [EDIT 16/11/2009]

    À toute fin utile, je signale que le problème s'est reproduit deux fois.

    Je n'ai pas la preuve absolue, mais je pense que c'est Dreamweaver 8 (2005) qui fait des choses étranges, très occasionnellement, lorsque l'ordinateur se fige quelques secondes à cause de la mise à jour du logiciel de sécurité (G Data InternetSecurity 2010).

    La dernière en date, lors de la vérification d'une toute petite mise à jour qui concernait toutes les pages d'un site, il n'y avait plus aucun caractère accentué dans le site ! Heureusement, je fais une sauvegarde chaque mardi, la panique a été de courte durée.

    Comme je code tout à la main, je ne m'étais pas aperçu que Dreamweaver 8 avait pris de l'âge. J'avais pris des habitudes confortables et c'est avec regret que je dois m'en séparer.

    J'ai testé Aptana pendant quelques jours, je le trouve trop lourd et trop lent au démarrage. Je n'arrive pas à prendre mes marques.

    Je me suis décidé pour Kopmodo Edit 5.2.2. Je constate qu'il n'y a pas d'espace dédié dans le forum outils. Si quelqu'un lit ceci et connaît un tutoriel ou une documentation en français, je suis très intéressé.

    N.B. : le patch français pour Komodo provoque un bug majeur, j'ai dû réinstaller Komodo pour en venir à bout.

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

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

Discussions similaires

  1. Erreur avec l'évènement OnClick de ListView
    Par xenos dans le forum Composants VCL
    Réponses: 2
    Dernier message: 21/03/2006, 14h54
  2. pointeur this - c++ builder
    Par mathieu57 dans le forum C++Builder
    Réponses: 7
    Dernier message: 03/03/2006, 14h19
  3. Pointeur de fonction événement.
    Par Bartman dans le forum C++Builder
    Réponses: 4
    Dernier message: 21/02/2006, 14h44
  4. [MFC] Pointeur this et fonctions statiques
    Par Yellowmat dans le forum MFC
    Réponses: 5
    Dernier message: 08/02/2005, 10h15
  5. Modification de l'évènement OnClick
    Par MrJéjé dans le forum C++Builder
    Réponses: 9
    Dernier message: 22/08/2002, 12h52

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