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 :

Utilisation de prototype et regex


Sujet :

JavaScript

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 15
    Points : 12
    Points
    12
    Par défaut Utilisation de prototype et regex
    Bonsoir tout le monde,

    Tout d'abord je tiens a dire que je suis débutant en Javascript, merci d'être indulgent

    Voilà, j'aimerai me lancer dans la création d'une fonction (j'ai essayé d'écrire une classe mais je n'ai pas encore les bonnes notions pour en faire en JavaScript).

    Je vous explique tout d'abord mon code HTML...

    Cela va être du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <div id="portefolio">
    <div id="picture_1" class="picture_portefolio"></div>
    <div id="content_2" class="content_portefolio"></div>
    <div id="picture_2" class="picture_portefolio"></div>
    <div id="content_2" class="content_portefolio"></div>
    <div id="picture_3" class="picture_portefolio"></div>
    <div id="content_2" class="content_portefolio"></div>
    </div>
    Lors du clique sur un picture_[0-9*] j'aimerai qu'il récupère le nombre pour ouvrir l'élément content_[nombre_reçu]

    Sachant que j'aimerai que quand je clique sur un autre élément, il me ferme celui qui est ouvert.

    Le problème pour moi est enfaite de récupérer le nombre dérrière et de lister les éléments déjà ouvert.

    Je pense que pour pouvoir lister tout les éléments déjà ouvert il faut utiliser Event.findElement()...


    Voilàa ce que j'ai fais :

    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
    var Portefolio = Class.create();
     
    Portefolio.prototype = {
    	initialize : function(element) {
    		this.element = $(element);
    	},
     
    	getInit : function() {
     
    		Event.observe('picture_[0-9*]', 'click', function()
    		{
    			content_open = Event.findElement(this.element, 'content_');
    			if(content_open != null)
    			{
    				Effect.BlindUp(content_open.tagName);
    			}
    			else
    			{
    				nbr = ??;
    				id_content = 'content_' + nbr;
    				Effect.toggle(id_content, 'slide');
    				if(id_content.visible())
    				{
    					Effect.ScrollTo(id_content);
    				}
    			}
     
    		}
     
    	}
     
     
    }
     
    Event.observe(window,'load',function(){ new Portefolio('portefolio'); });
    Pouvez vous me donner un coup de main s'il vous plait ?

    Merci d'avance,
    Cordialement

  2. #2
    Membre expérimenté
    Avatar de gwyohm
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2007
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 925
    Points : 1 333
    Points
    1 333
    Par défaut
    Bonjour et bienvenue sur le forum,

    Tout d'abord, je ne sais pas quelle version de prototype tu utilises, mais depuis les dernières versions (1.6), la création de classes a été simplifiée :
    plus besoin de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    var MaClasse = Classe.create();
    MaClasse.prototype = {
      initilaize: function() {
      },
      methode1: function() {
     
      }
    };
    tu peux faire directement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    var MaClasse = Classe.create({
      initilaize: function() {
      },
      methode1: function() {
     
      }
    });
    Pour revenir maintenant à test questions, tu peux certainement stocker le dernier élément ouvert
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    var Portefolio = Class.create({
      initialize: function(element) {
        this.element = $(element);
        // definition d'un membre pour stocker le 
        // dernier element ouvert par defaut à null
        this.openedPicture = null;
        // appelons l'init tout de suite
        this.getInit();
      }
      // ...
    });
    Ensuite, la syntaxe de sélection d'élément par expression régulière ne va pas fonctionner, Event.observe attend en premier paramètre un id ou un element. Pour toi l'objectif est d'appliquer le même listener à tous les éléments dont l'id suit l'expression régulière que tu as saisi, mais plus simplement à tous les enfants de element dont la classe css est picture_portefolio.
    Tu peux récupérer tous ces éléments dans un tableau en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    this.element.select(".picture_portefolio")
    Comme tu auras un tableau, tu dois soit boucler sur ce tableau pour attacher le listener via une boucle simple ou via la méthode each que prototype fourni pour les Enumerable, soit en invoquant pour tous ces éléments la méthode observe :
    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
     
    var pictures = this.element.select(".picture_portefolio");
    for(var i=0,size=pictures.length;i<size;i++) {
      pictures[0].observe("click", function(e){});
      // equavalent à Event.observe(pictures[0], "click", function(e){});
    }
    // ou bien
    var pictures = this.element.select(".picture_portefolio");
    // la méthode each appel la fonction passée en paramètre 
    // pour chacun des éléments de l'Enumerable
    pictures.each(function(picture) {
      picture.observe("click", function(e){});
      // equavalent à Event.observe(picture, "click", function(e){});
    });
    // ou bien
    var pictures = this.element.select(".picture_portefolio");
    pictures.invoke("observe", "click", function(){});
    Pour ce qui est du code du listener "click", le problème c'est que tu as besoin d'une référence à l'objet Portfolio courant (pour avoir this.element ou this.openedPicture) Cependant, dans le contexte d'un listener, la fonction est hors du scope de l'objet, il faut donc explicitement lier le listener à l'objet courant, ceci est fait en appelant la méthode bindAsEventListener de l'objet function.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    for(var i=0,size=pictures.length;i<size;i++) {
      pictures[0].observe("click", function(e){}.bindAsEventListener(this));
      // equavalent à Event.observe(pictures[0], "click", function(e){}.bindAsEventListener(this));
    }
    // ou bien 
    pictures.invoke("observe", "click", function(e){}.bindAsEventListener(this));
    petite remarque, avec la syntaxe .each, on se trouve aussi dans une fonction "anonyme", il faut donc passer en deuxième paramètre du each le contexte courant (qui est this dans la méthode d'itération) en l'occurence c'est this :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    pictures.each(function(picture) {
      picture.observe("click", function(e){}.bindAsEventListener(this));
      // equavalent à Event.observe(picture, "click", function(){}.bindAsEventListener(this));
    }, this);
    En ayant fait ça, quand le listener sera executé, le this courant sera l'objet portfolio.
    on peut donc
    1/ recuperer l'element cliqué via l'evenement (le paramètre e du listener)
    2/ avec l'element cliqué, on peut trouver l'element contenu correspondant (grace à une expression reguliere par exemple)
    3/ masquer l'element ouvert s'il n'est pas null et different de l'element à afficher
    et ca donne ca :
    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
     
    pictures.invoke("observe", "click", function(e){
      // recuperons l'element clique 
      var clickedElem = e.element();
      // son id
      var clickedElemID = clickedElem.identify();
      // determinons l'id de l'element à afficher
      var displayElementID = "content_" + clickedElemID.match(/picture_([0-9]*)/)[1];
      // si l'element actuellement visible est celui actuellement visible, on a fini
      if(this.openedPicture != null && this.openedPicture.identify() == displayElementID ) {
        return;
      }
      // si l'element visible n'est pas null, on le masque
      if(this.openedPicture != null ) {
        new Effect.BlindUp(this.openedPicture);
      }
      // l'element affiché est maintenant celui dont l'id est displayElementID 
      this.openedPicture = $(displayElementID);
      // affichons le 
      new Effect.BlindDown(this.openedPicture);
    }.bindAsEventListener(this));

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    Merci pour toutes ses réponses !

    En effet j'utilise la version 1.6, merci pour la suggestion

    Concernant tes réponses, j'avoue ne pas avoir tout compris.. Mais étant donné que je débute, c'est normal... J'ai un peu regardé la doc de prototype des fonctions que tu m'as suggéré d'utiliser et j'y vois un peu plus clair...

    Si je comprend bien je dois procéder ainsi ?

    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
    var Portefolio = Class.create({
      initialize: function(element) {
        this.element = $(element);
        // definition d'un membre pour stocker le 
        // dernier element ouvert par defaut à null
        this.openedPicture = null;
        // appelons l'init tout de suite
        this.getInit();
      }
    	getInit : function() {
    		pictures.invoke("observe", "click", function(e){
    			  // recuperons l'element clique 
    			  var clickedElem = e.element();
    			  // son id
    			  var clickedElemID = clickedElem.identify();
    			  // determinons l'id de l'element à afficher
    			  var displayElementID = "content_" + clickedElemID.match(/picture_([0-9]*)/)[1];
    			  // si l'element actuellement visible est celui actuellement visible, on a fini
    			  if(this.openedPicture != null && this.openedPicture.identify() == displayElementID ) {
    				return;
    			  }
    			  // si l'element visible n'est pas null, on le masque
    			  if(this.openedPicture != null ) {
    				new Effect.BlindUp(this.openedPicture);
    			  }
    			  // l'element affiché est maintenant celui dont l'id est displayElementID 
    			  this.openedPicture = $(displayElementID);
    			  // affichons le 
    			  new Effect.BlindDown(this.openedPicture);
    		}.bindAsEventListener(this));
    	}
    });

  4. #4
    Membre expérimenté
    Avatar de gwyohm
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2007
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 925
    Points : 1 333
    Points
    1 333
    Par défaut
    oui, c'est presque ça : dans ton code pictures n'est jamais défini...

    Je ne peux que t'encourager à lire l'API prototype dans son ensemble ; ca parait long, mais on découvre des outils dont on ne soupçonne même pas l'existence... qui en général facilitent énormément la vie.

    Bonne chance pour la suite

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    En effet...

    Comme cela alors ?


    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
    var Portefolio = Class.create({
      initialize: function(element) {
        this.element = $(element);
        // definition d'un membre pour stocker le 
        // dernier element ouvert par defaut à null
        this.openedPicture = null;
        // appelons l'init tout de suite
        this.getInit();
      }
    	getInit : function() {
                    var pictures = this.element.select(".picture_portefolio");
    		pictures.invoke("observe", "click", function(e){
    			  // recuperons l'element clique 
    			  var clickedElem = e.element();
    			  // son id
    			  var clickedElemID = clickedElem.identify();
    			  // determinons l'id de l'element à afficher
    			  var displayElementID = "content_" + clickedElemID.match(/picture_([0-9]*)/)[1];
    			  // si l'element actuellement visible est celui actuellement visible, on a fini
    			  if(this.openedPicture != null && this.openedPicture.identify() == displayElementID ) {
    				return;
    			  }
    			  // si l'element visible n'est pas null, on le masque
    			  if(this.openedPicture != null ) {
    				new Effect.BlindUp(this.openedPicture);
    			  }
    			  // l'element affiché est maintenant celui dont l'id est displayElementID 
    			  this.openedPicture = $(displayElementID);
    			  // affichons le 
    			  new Effect.BlindDown(this.openedPicture);
    		}.bindAsEventListener(this));
    	}
    });
    Pour la doc de prototype, je suis d'accord.

    En tout cas bravo à toi, combien d'années dans le JS et l'utilisation de l'API prototype ?

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    lors du

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new Effect.BlindUp(this.openedPicture);
    Vaut bien le nom de l'id, mais étant donné qu'il est lui même dans l'id portefolio cela pose un problème.. Enfin du moins cela ne fonctionne pas ... J'ai mis des alert un peu partout... Tout es bien renvoyé correctement .. Après c'est pour ouvrir et fermer ... As tu une idée ?

  7. #7
    Membre expérimenté
    Avatar de gwyohm
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2007
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 925
    Points : 1 333
    Points
    1 333
    Par défaut
    je suis pas sur d'avoir saisi le problème.
    Teste en remplaçant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    new Effect.BlindUp(this.openedPicture); 
    //par 
    this.openedPicture.hide();
    // et
    new Effect.BlindDown(this.openedPicture); 
    //par 
    this.openedPicture.show()
    Si ca fonctionne, on a peut-être une collision de reference, essaye alors avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new Effect.BlindUp(this.openedPicture.identify());

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    Ne fonctionne malheureusement pas ...

    Rien ne se ferme, ou s'ouvre...

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    J'ai réussi a me faire un petit truc sympa ...

    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
    function addEvent(obj, type, fn) {
    	if( obj.attachEvent ) {
    			obj["e"+type+fn] = fn;
    			obj[type+fn] = function(){obj["e"+type+fn]( window.event );};
    			obj.attachEvent( "on"+type, obj[type+fn] );
    	} else {
    			obj.addEventListener( type, fn, true );
    	};
    }
     
    Event.observe(window, 'load', function()
    {
    	$$('.portefolio').each(function(obj,index){
    		addEvent(obj,'click',function(){
    			// Quand on reclique sur l'élément on le ferme
    			if($('portefolio'+obj.id.replace('picture_','content_')).visible()){
    				Effect.BlindUp($('portefolio'+obj.id.replace('picture_','content_')), {duration:0.4}); 
    			} else {
    				// on ferme les autres éléments ouvert
    				$$('.portefolio').each(function(obj,index){
    					if($('portefolio'+obj.id.replace('picture_','content_')).visible()) {
    						Effect.BlindUp($('portefolio'+obj.id.replace('picture_','content_')), {duration:0.4});
    					}
    				});
    				// On ouvre l'élément
    				Effect.BlindDown($('portefolio'+obj.id.replace('picture_','content_')), {duration:0.5});
    				Effect.ScrollTo($('portefolio'+obj.id.replace('picture_','content_')));
    			}
    		});
    	});
     
    	// On ferme tout les éléments
    	$$('.portefolio').each(function(obj,index){
    		if($('portefolio'+obj.id.replace('picture_','content_')).visible()) {
    			$('portefolio'+obj.id.replace('picture_','content_')).hide();
    		}
    	});
     
    });
    Voilà la source, si ça intéresse quelqu'un

    Merci de ton aide !

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

Discussions similaires

  1. POO par l'utilisation du prototype
    Par narfight dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 01/10/2012, 09h18
  2. [Prototype] Utilisation de prototype.js
    Par cyberlp dans le forum Bibliothèques & Frameworks
    Réponses: 1
    Dernier message: 22/01/2009, 16h11
  3. [Prototype] L'utilisation de Prototype.js ne permet plus le tri
    Par Malola dans le forum Bibliothèques & Frameworks
    Réponses: 2
    Dernier message: 21/11/2008, 22h51
  4. Réponses: 9
    Dernier message: 30/11/2005, 18h18
  5. Utilisation de regex : TRegExpr
    Par trakiss dans le forum Langage
    Réponses: 2
    Dernier message: 22/06/2005, 23h07

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