11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour, j'ai créé un slider, sauf qu'on me demande de réécrire mon code en orienté objet et là!
Ma tête brûle.
Voici le code, si quelqu'un peut prendre un peu de son temps. Merci
var slides = document.querySelectorAll('.slide');
var buttRight = document.querySelector('.butt-suivant');
var buttLeft = document.querySelector('.butt-precedent');
var buttPause = document.querySelector('.butt-pause');

var index = 0;
	
	function slideSuivant(){
		slides[index].classList.remove('slide-active');
		if(index === 3){
		index = -1;
	}
		slides[index+1].classList.add('slide-active');
		index = index + 1;
	};
	//slide suivant au click
	buttRight.addEventListener('click', function(){
		slides[index].classList.remove('slide-active');
		if(index === 3){
		index = -1;
	}
		slides[index+1].classList.add('slide-active');
		index = index + 1;
	});

	//slide précédent au click
	buttLeft.addEventListener('click', function(){
		slides[index].classList.remove('slide-active');
		if(index === 0){
		index = 3;
	}
		slides[index-1].classList.add('slide-active');
		index = index-1;
	});

	//slide auto
	var idInterval = window.setInterval(function(){
		slideSuivant();
	},2000);//Défilement des images toutes les 2 secondes

	//stop du slide auto
	buttPause.addEventListener('click', function(){
		if (buttPause.classList.contains('enpause')) {//en pause->il relance le timer
		window.clearInterval(idInterval);
		idInterval = window.setInterval(function(){
		slideSuivant();
	},2000);
	buttPause.classList.remove('enpause');
	}else{//n'est pas en pause->il met en pause
		window.clearInterval(idInterval);
		buttPause.classList.add('enpause');
	}			
	});
Salut

En gros tu devrais créer une var Slider {} qui prendrait toutes les fonctions à l'intérieur ce qui te permettrait de faire un SetInterval(Slider.next(200))) un truc du genre

Un peu comme ça :

var Diaporama= {     
element:document.getElementById('slide'), // Attribut de sélection des images     
imageNum:0,   // Attribut qui permet de parcourir les images    
images:["img1.jpeg","img2.jpeg", "img3.jpeg"],
boucle:null,  
 
   this.idSlide = id;
        this.imgs = imgs;
        this.domSlide = document.getElementById(this.idSlide);
    this.domImg = this.domSlide.querySelector('img');
    this.domPrev = this.domSlide.querySelector('div .prevBtn');
    this.domNext  = this.domSlide.querySelector('div .nextBtn');
    this.domPause  = this.domSlide.querySelector('div .pauseBtn');
 
 
// Méthode qui fait fonctionner le diaporama en avant     
suivant: function() {   
        this.imageNum++;  
    if (this.imageNum > (this.images.length - 1)) {
            this.imageNum = 0;
        }
        this.element.src = this.images[this.imageNum];
    },
 
// Méthode qui fait fonctionner le diaporama en arrière   
precedent: function() {     
        this.imageNum--;
        if (this.imageNum < 0) {
            this.imageNum = this.images.length - 1;
        }
        this.element.src = this.images[this.imageNum];
    },
 
//Fonction clavier 
  keyboard: function(e){
        switch(e.keyCode){
            case 37: // left
                this.suivant();
                break;
            case 39: // right
                this.precedent();
                break;
 
                        }
                        } 
 
        // Gestionnaires d'événements et Action !
    document.addEventListener('keydown', this.keyboard.bind(this));
    this.domPrev.addEventListener('click', this.precedent.bind(this));
    this.domNext.addEventListener('click', this.suivant.bind(this));
 
 
}
 
var boucle = setInterval(Diaporama.suivant.bind(Diaporama), 2500);



Ce code n'est pas de moi.
Si j'ai bien compris quand on dit orienté Object, c'est créer un objet que l'on peut rappeler/introduire là et quand on le souhaites?

C'est un peu comme React dit vulguairement et différent de la programmation séquentiel.

Je fais du JS depuis 4 mois et du React depuis 1 mois et demi et je comprends pas totalement encore la POO.

Merci
Salut, JENCAL,
j'avais testé ceci à quelques différences prés. ça m'a l'air cohérent. Je le réessaie je vois.
Merci encore une fois d'avoir pris de ton temps. Je te ferai un retour
Hello Yendia,
Alors en fait non, la programmation orientée objet (POO) en JS est comme dans les autres langages une histoire d'instanciation d'objets à partir d'une classe (ou d'une fonction avant l'es6) et pas simplement un objet JS avec des propriétés et méthodes statiques.
Qui dit POO, dit "new" et "this" à un moment ou un autre.

Dans ton cas, l'exemple de Jencal va casser dès que tu auras 2 ou ou plus sliders dans ta page.
Voici un excellent sujet sur MDN en version avant es6 : https://developer.mozilla.org/fr/docs/Learn/JavaScript/Objects/JS_orient%C3%A9-objet
Mais JS dispose aujourd'hui de "class", "constructor" et tout plein de fonctionnalités pour la POO : https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Classes

Pour revenir à ton cas ça pourrait faire ça : https://codepen.io/korell/pen/dyPZMEr

class Slider {

    /**
     * dans le constructeur de la classe, il y a toutes les actions à faire lors de l'instantiation de celle-ci
     * @param container
     */
    constructor(container) {
        this.currentIndex = 0;
        this.isPaused = false;
        this.slides = container.querySelectorAll('.Slide');
        this.btnPrev = container.querySelector('.Navigation-btn--prev');
        this.btnNext = container.querySelector('.Navigation-btn--next');
        this.btnPause = container.querySelector('.Navigation-btn--pause');
        this.lastIndex = this.slides.length - 1;

        //initialisation des événements sur les boutons
        this.bindEvents();

        //initialisation de la première slide
        this.slideToIndex(this.currentIndex, false);

        //lancement de l'autoplay
        this.startAutoplay();
    }

    autoplay() {

        // si le slider était en pause on slide immédiatement à la suivante
        if(this.isPaused) {
            this.slideToNext(false);
        }

        // on stocke un timer que l'on pourra clear plus tard
        this.timer = setTimeout(() => {
            this.slideToNext(false);

            // fonction récursive
            this.autoplay();
        }, 2000)
    }
    
    bindEvents() {
        this.btnPrev.addEventListener('click', () => this.slideToPrev())
        this.btnNext.addEventListener('click', () => this.slideToNext())
        if(this.btnPause) {
            this.btnPause.addEventListener('click', () => this.toggleAutoplay())
        }
    }
    
    slideToPrev() {
        this.currentIndex = this.currentIndex - 1 > -1 ? this.currentIndex - 1 : this.lastIndex;
        this.slideToIndex(this.currentIndex);
    }

    slideToNext(pauseSlider = true) {
        this.currentIndex = this.currentIndex + 1 <= this.lastIndex ? this.currentIndex + 1 : 0;
        this.slideToIndex(this.currentIndex, pauseSlider);
    }

    /**
     *
     * @param index
     * @param pauseSlider:boolean
     *    indique si on doit stopper l'autoplay quand on change de slide
     */
    slideToIndex(index, pauseSlider = true) {
        if(pauseSlider) {
            this.pauseAutoplay();
        }
        // suppression de la classe 'active' pour toutes les slides du slider
        this.slides.forEach( slide => {
            slide.classList.remove('slide-active');
        })

        // avant d'appliquer d'activer l'index désiré
        this.slides[index].classList.add('slide-active');
    }

    pauseAutoplay() {
        if(this.btnPause) {
            this.btnPause.innerText = 'Lecture automatique';
        }
        clearTimeout(this.timer);
        this.isPaused = true;
    }

    startAutoplay() {
        if(this.btnPause) {
            this.btnPause.innerText = 'Pause'
        }
        this.autoplay();
        this.isPaused = false;
    }

    toggleAutoplay() {
        if(!this.isPaused) {
            this.pauseAutoplay();
        }else {
            this.startAutoplay();
        }
    }
}

// on recherche dans le DOM tous les sliders existants
// et on instancie un nouvau slider pour chaque élément du DOM
document.querySelectorAll('[data-slider-element="slider-container"]').forEach( (slider) => {
    new Slider(slider)
});


Bon dev Smiley smile
Modifié par Tony Monast (03 Jan 2020 - 22:19)
Merci MatthieuR, ça fonctionne bien, c'est juste les événements clavier qui marchent pas.
Big up pour le temps consacré
Meilleure solution