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 :

Référence à un objet


Sujet :

JavaScript

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 56
    Par défaut Référence à un objet
    Bonjour à tous !

    Pour expliciter le contexte, dans le cadre d'un projet, j'ai pas le droit à jQuery Mais j'ai le droit de plus ou moins le refaire ^^ Je me suis donc lancé dans cette aventure, mais je bloque sur un soucis de "context" je dirais...

    Sur le code qui va suivre, tout fonctionne presque Seul soucis : en cas de fonctions avec timer (animation, par exemple), si deux animation se croise, l'objet courant dans l'animation est le dernier appelé. Forcément, pour faire un callback, ça le fait pas du tout...

    Pour le moment, $('element') ne récupère qu'un élément HTML d'ID "element". Ce sera améliorer par la suite, quand j'aurais résolu ce problème de "this"..

    Voilà le code ^^

    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    <script type="text/javascript">
    (function(){
    		jWibi = window.$ = function(selector, context) {
    			return jWibi.init(selector, context);
    		};
    		jWibi = jWibi.prototype = {
    			version: '1.0',
    			selector: null,
    			init: function(selector){
    				selector = selector || document;
    				if(typeof selector === 'string'){
    					this.selector = document.getElementById(selector);
    				}
    				return this;
    			},
    			get: function () { return this.selector; },
    			html: function(str){
    				if(str){
    					this.selector.innerHTML = str;
    					return this;
    				}else return this.selector.innerHTML;
    			},
    			css: function(s, v){
    				if(s != null && v != null && typeof s === 'string' && typeof v === 'string'){
    					this.selector.style[s] = v;
    				}else if(s != null && typeof s === 'object'){
    					var nb = arguments.length;
    					if(nb > 1) for(a in s) this.selector.style[a] = s[a];
    					else{
    						for(i=1;i<=nb;i++){
    							for(a in s) this.selector.style[a] = s[a];
    						}
    					}
    				}
    				return this;
    			},
    			ready: function (func) {
    				if (typeof window.onload != 'function') { window.onload = func; }
    				else { window.onload = function() { window.onload(); func(); } }
    				return window;
    			},
    			click: function (func) {
    				if (typeof this.selector.onclick != 'function') { this.selector.onclick = func; }
    				else { this.selector.onclick = function() { this.selector.onclick(); func(); } }
    				return this;
    			},
    			toggle: function() {
    				this.selector.style.display = (this.selector.style.display === 'none' || '') ? 'block' : 'none';
    				return this;
    			},
    			opacity: function(level) {
    				if(level>=0 && level<=100) {
    					this.selector.style.opacity = (level/100);
    					this.selector.style.filter = 'alpha(opacity='+level+')';
    				}
    			},
    			fadeOut: function(time) {
    				var level = 100;
    				var iout = setInterval(function(){
    					$(this.selector).opacity(level--);
    					if(level==0){ clearInterval(iout); }
    				},time/100);
    				return this;
    			},
    			fadeIn: function(time) {
    				level = 0;
    				var iin = setInterval(function(){
    					$(this.selector).opacity(level++);
    					if(level==100){ clearInterval(iin); }
    				},time/100);
    				return this;
    			},
    			timers: new Array(),
    			launchAnim: function(obj, elt, i, currentValue, finishValue, pas, plus, moins, timeRefresh, callback){
    				currentValue += pas;
    				var objthis = obj;
    				ecart = parseFloat(finishValue - currentValue);
    				if(plus && ecart > 0 || moins && ecart < 0){
    					elt.style[i] = currentValue;
    					setTimeout(function(){$().launchAnim(obj, elt, i, currentValue, finishValue, pas, plus, moins, timeRefresh, callback)}, timeRefresh);
    				}else{
    					currentValue = finishValue;
    					elt.style[i] = currentValue;
    					var testouille1 = elt.getAttribute("id");
    					var testouille2 = obj.selector.getAttribute("id");
    					console.log('elt : '+testouille1+', obj: '+testouille2);
    					//callback.call(obj);
    				}
    				return this;
    			},
    			animate: function(anim, time, callb){
    				var animation = anim;
    				var duration = time;
    				var callback = callb || function(){return;};
    				var timeRefresh = 20;
    				var nbRefresh = parseFloat(duration / timeRefresh);
    				for(var i in animation){
    					var currentValue = parseFloat(this.selector.style[i]);
    					var finishValue = parseFloat(animation[i]);
    					var ecart = parseFloat(finishValue - currentValue);
    					if(ecart < 0){var plus = false;var moins = true;}
    					else if(ecart > 0){var plus = true;var moins = false;}
    					else return this;
    					var pas =  parseFloat(ecart / nbRefresh);
    					var obj = this;
    					var Class = $(this);
    					var num = this.timers.length;
    					this.timers[num] = obj;
    					this.launchAnim(Class, obj.selector, i, currentValue, finishValue, pas, plus, moins, timeRefresh, callback);
    				}
    				return this;
    			}, 
    			callbacker: function (func) {
    				if (typeof this.selector.callback != 'function') { this.selector.callback = func; }
    				else { this.selector.callback = function() { this.selector.callback(); func(); } }
    				return this;
    			}
    		}
    })();
    </script>
    Et pour le test :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <script type="text/javascript">
    $().ready(function () {
      $('test').animate({'height':'150px'}, 1000, function(){$(this).css('background','#f00')});
      $('test2').animate({'height':'20px'}, 2000, function(){$(this).css('background','#f55')});
    });
    </script>
    <div id="test">test</div>
    <div id="test2">test 2</div>
    Dans la fonction "launchAnim", le console.log() devrai ressortir :
    elt : test, obj: test
    elt : test2, obj: test2
    Mais il ressort :
    elt : test, obj: test2
    elt : test2, obj: test2
    J'ai un peu tout essayé, tout bidouiller, j'ai meme mis les "this" à l'appel en array mais malgré ça, ils sont tous remplacé par le dernier appelé, même dans l'array..

    Quelqu'un voit peut-être d'où vient le soucis ?
    J'ai bien la notion de "contexte" dans mon "init", mais je n'ai pas compris comment l'utiliser, peut être pourrait-il m'aider.. Certainement même.

    Merci d'avance à ceux qui liront

  2. #2
    Expert éminent

    Avatar de vermine
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    6 582
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2008
    Messages : 6 582
    Par défaut
    Bonjour,

    A quoi vous sert cette instruction ?


  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 56
    Par défaut
    Citation Envoyé par vermine Voir le message
    Bonjour,

    A quoi vous sert cette instruction ?

    À rien, elle était là quand je voulais essayer de conserver localement l'objet instancié..
    [EDIT] pas l'objet instancié directement, mais celui passé en paramètre. 'fin dans tous les cas, ça marchait pas. On sent le désespoir de cause dans mon code, désolé

  4. #4
    Expert éminent

    Avatar de vermine
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    6 582
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2008
    Messages : 6 582
    Par défaut Fourberie !
    obj.selector est en fait var obj = this;. Ca porte à confusion car ce qui bloque c'est var Class = $(this); qui devient obj.selector.

    Changez le nom de votre variable "Class". C'est pas top d'utiliser un nom réservé (j'hésite à cause de la majuscule).

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 56
    Par défaut
    Citation Envoyé par vermine Voir le message
    obj.selector est en fait var obj = this;. Ca porte à confusion car ce qui bloque c'est var Class = $(this); qui devient obj.selector.

    Changez le nom de votre variable "Class". C'est pas top d'utiliser un nom réservé (j'hésite à cause de la majuscule).
    Voui je peux changer le terme "Class", je l'ai mis suite à une probable solution trouvé sur un forum.
    Du coup euh.. C'était quoi la solution ? ^^

    De base, personnellement j'avais juste mis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.launchAnim(this, this.selector, i, currentValue, finishValue, pas, plus, moins, timeRefresh, callback);
    Dans launchAnim, this.selector (elt) était bon dans le console.log(), mais this (obj) ne l'était pas, et ne se rapportait qu'au dernier objet instancié..

    [EDIT] Euh sinon, this != this.selector ; en faisant $(elt), ça retourne l'objet, le selector est ensuite à l'intérieur de cet objet

    [EDIT] Arf okay viens de voir, normalement c'est pas Class qui est passé en parametre mais obj. Ca fait parti de toutes mes manipulations pour essayer de cerner le problème..

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 56
    Par défaut Site de test
    En fait après encore moults tests, j'ai l'impression qu'on ne peut pas stocker "this" en variable..
    Si je fais un array, tab[], et qu'à chaque nouvelle instance j'enregistre
    Eh bien en bouclant sur tab, je me rend compte que tous les this sont identiques, sont tous comme "écrasé" par le dernier.
    Dingue.

    En guise d'exemple, voilà une page qui cible le problème, le code est raccourcis à l’extrême : http://www.wibimaster.com/findError/
    Dans la console, 4 lignes s'afficheront,le problème se distingue à la 3e..

  7. #7
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Billets dans le blog
    20
    Par défaut
    Là il s'agit d'une affectation type PHP, mais ce n'est pas valable en JavaScript.
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 56
    Par défaut
    Yep, j'ai écrit ça à la va-vite pour le forum, mais dans tous les cas ça ne marche pas.. Il faut regarder la page test, et la source qui est beaucoup plus concise montre directement le soucis. Pour ne pas dénaturer le post, je n'ai pas éditer le 1er message, donc je vais mettre la source ici :

    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
    (function(){
    	jWibi = window.$ = function(selector, context) {
    		return jWibi.init(selector, context);
    	};
    	jWibi = jWibi.prototype = {
    		version: '1.0',
    		selector: null,
    		init: function(selector){
    			selector = selector || document;
    			if(typeof selector === 'string'){
    				this.selector = document.getElementById(selector);
    			}
    			return this;
    		},
    		ready: function (func) {
    			if (typeof window.onload != 'function') { window.onload = func; }
    			else { window.onload = function() { window.onload(); func(); } }
    			return window;
    		},
    		launchAnim: function(obj, elt, i){
    			if(i == 0)
    				console.log('Premier passage :: Objet.selector (ID) = '+obj.selector.getAttribute('id')+', Element (ID) = '+elt.getAttribute('id'));
    			else
    				console.log('Timeout :: Objet.selector (ID) = '+obj.selector.getAttribute('id')+', Element (ID) = '+elt.getAttribute('id'));
    			i++;
    			if(i < 2) setTimeout(function(){$().launchAnim(obj, elt, i)}, 500);
    		},
    		animate: function(){
    			this.launchAnim(this, this.selector, 0);
    			return this;
    		}
    	}
    })();
    $().ready(function () {
    	$('test').animate();
    	$('test2').animate();
    });
    Avec code comme HTML :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <div id="test" style="height: 20px;background: #f00">test</div>
    <div id="test2" style="height: 200px;background: #ff0">test2</div>
    Et les logs de console à l'exécution :

    Premier passage :: Objet.selector (ID) = test, Element (ID) = test
    Premier passage :: Objet.selector (ID) = test2, Element (ID) = test2
    Timeout :: Objet.selector (ID) = test2, Element (ID) = test
    Timeout :: Objet.selector (ID) = test2, Element (ID) = test2
    On voit à la 3e ligne que l'objet n'est plus le bon..

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 56
    Par défaut Solution
    Bien, après avoir écumé d'autres forum, j'ai finit par trouver deux solutions à ce problème. Je post ici la réponse la plus simple, sait-on jamais que quelqu'un en ait besoin, et puis histoire de le marquer comme résolu...

    Code salvateur :

    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
    (function(){
    	jWibi = window.$ = function(selector, context) {
    		// Si jWibi est appelé directement, on le rappelle avec new
    		// Création d'une instance, donc.
    		if(!(this instanceof jWibi)) return new jWibi(selector, context);
    		selector = selector || document;
    		if(typeof selector === 'string'){
    			this.selector = document.getElementById(selector);
    		}
    		return this;
    		// Ici on est sûr d'avoir une instance.
    	};
    	jWibi.prototype = {
    		version: '1.0',
    		selector: null,
    		ready: function (func) {
    			if (typeof window.onload != 'function') { window.onload = func; }
    			else { window.onload = function() { window.onload(); func(); } }
    			return window;
    		},
    		launchAnim: function(obj, elt, i){
    			if(i == 0)
    				console.log('Premier passage :: Objet.selector (ID) = '+obj.selector.getAttribute('id')+', Element (ID) = '+elt.getAttribute('id'));
    			else
    				console.log('Timeout :: Objet.selector (ID) = '+obj.selector.getAttribute('id')+', Element (ID) = '+elt.getAttribute('id'));
    			i++;
    			if(i < 2) setTimeout(function(){$().launchAnim(obj, elt, i)}, 500);
    		},
    		animate: function(){
    			this.launchAnim(this, this.selector, 0);
    			return this;
    		}
    	}
    })();
    Pour le moment pas vu de problème avec ça, ça m'a l'air parfait

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 11/07/2006, 17h27
  2. [VB6] faire référence à un objet situé sur un autre form
    Par coyott dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 15/05/2006, 15h13
  3. Référence à un objet existant depuis une classe
    Par Adrenalys dans le forum ASP
    Réponses: 2
    Dernier message: 21/07/2005, 00h44

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