10597 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Je me permets de poster ce message car je bloque sur un point.
J'ai créé une class (un petit slider très simplifié pour exposer mon problème).
Je souhaite faire défiler automatiquement les blocs contenant du texte.
Pour ce faire, j'utilise setInterval afin que la méthode chargée de modifier l'index des blocs soit exécutée toutes les 1000 millisecondes.

Lorsque j'utilise setInterval, la console renvoie un message d'erreur :
Uncaught TypeError: Cannot read property 'undefined' of undefined

Je n'arrive pas à comprendre pourquoi.
Sauriez-vous m'expliquer ?

Le code est ici (fonctionnel mais je ne comprends pas pourquoi la ligne ci-dessous ne permet pas le défilement automatique) :

this.interval = setInterval(this.imgSuivante, 1000);


Merci Smiley smile
Tu as cette erreur, car dès le début à la première itération de :
this.slides[this.index].style.display = "none";


parce que this.index est UNDEFINED
parce que tu ne garde pas le context this.

dans l'exemple qui fonctionne on voit bien le .bind(this) que tu ne met pas dans la ligne que toi tu as faite. Du coup il a pas d'index.

solution :
this.interval = setInterval(this.imgSuivante.bind(this), 1000);
Merci de ta réponse Smiley smile

La première itération contient-elle une erreur ?

"parce que this.index est UNDEFINED
parce que tu ne garde pas le context this."


this.slides[this.index].style.display = "none";


"dans l'exemple qui fonctionne on voit bien le .bind(this) que tu ne met pas dans la ligne que toi tu as faite. Du coup il a pas d'index."

Je vais me documenter sur le .bind(this). C'est encore un peu abstrait.

Enfin, le .bind(this) est-il le seul moyen d'obtenir le résultat souhaité dans le cas de mon exemple ?
Modifié par MickFR (17 Jun 2019 - 16:01)
Oué, mais attention à Bind

=>

.bind()
Categories: Deprecated > Deprecated 3.0 | Events > Event Handler Attachment
JENCAL a écrit :
Oué, mais attention à Bind

=>

.bind()
Categories: Deprecated > Deprecated 3.0 | Events > Event Handler Attachment

ça c'est le bind de jQuery, ce bind là est pas du tout deprecated, et est parfaitement safe du moment qu'on est en ECMAScript 2015 (ce qui est le cas du reste du code)

https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Function/bind
Modifié par kustolovic (17 Jun 2019 - 16:44)
Sinon sans le bind:


this.interval = setInterval(this.imgSuivante.bind(this), 1000);

// OU

var self = this;
this.interval = setInterval(function(){ self.imgSuivante(); }, 1000);


c'est plus propre avec
Bonjour,

Merci de vos réponses Smiley smile
Je vais donc utiliser .bind.

Aussi, en reprenant mon exemple, j'aimerais remplacer le code ci-dessous par une fonction :
this.slides[this.index].style.display = "none";


La fonction :
function afficher(index){
   slides[index].style.display = 'block';
}


Je n'arrive pas à faire fonctionner cette fonction dans ma classe.
Le code que j'ai écrit est ici.

Auriez-vous une piste à me donner ?
J'ai lu de la documentation sur MDN mais je n'arrive pas à débloquer le problème.

Merci Smiley smile
Modifié par MickFR (18 Jun 2019 - 10:50)
Alors .bind retourne une fonction, mais ne l'éxecute pas.

dans ton appel il est inutile:


imgSuivante() {
  this.masquer.bind(this.index); //FONCTION MASQUER
  this.index++;
  if (this.index > this.slides.length - 1) {
    this.index = 0;
  }
  this.afficher.bind(this.index); //FONCTION AFFICHER
}


écrire plutôt:


imgSuivante() {
  this.masquer(this.index); //FONCTION MASQUER
  this.index++;
  if (this.index > this.slides.length - 1) {
    this.index = 0;
  }
  this.afficher(this.index); //FONCTION AFFICHER
}


bind est utile quand tu passe en argument une fonction qui sera exécutée plus tard, car sinon la fonction est découplée de l'instance et n'a plus la référence au this, comme dans setInterval ou dans un eventListener.
Meilleure solution
Salut,

Merci de ta réponse précise Smiley smile
Je vais continuer à me documenter sur bind.

J'ai fait évoluer mon code. J'ai ajouté un petit bouton.
Lorsqu'on clique dessus, j'aimerais que le texte du bouton devienne rouge.

Pour ce faire, j'ai ajouté les méthodes suivantes :
changerCouleur(){
    this.btn.style.color = 'red';
  }


clic(){
  this.btn.addEventListener('click', function(){
			this.changerCouleur();
		});
  }


Lorsque je clique sur le bouton, la console affiche le message suivant :
Uncaught TypeError: this.changerCouleur is not a function

Cette erreur vient-elle du this ?

Je suis un peu perdu Smiley decu

Le CodePen est ici.

Merci de votre aide Smiley smile
Modifié par MickFR (26 Jun 2019 - 15:14)