0

I'm trying for an exercise to create a slideshow without jquery. I'm trying to learn the OO in Javascript.

'use strict';

var Slideshow = (function () {

function Slideshow(element, options) {
    options = options || {};
    this.slideshow = document.querySelector(element || '.slideshow');
    this.slides = this.slideshow.children;
    this.slideSpeed = options.slideSpeed || 3000;
    this.autoPlay = options.autoPlay || true;
    this.pauseOnHover = options.pauseOnHover || true;
    this.autoPlayTimer = null;
    this.pause = false;
    this.currentSlide = -1;

    if (this.autoPlay) {
        this.play();
    }
}

Slideshow.prototype.slideIterator = function() {
    this.currentSlide = (this.currentSlide + 1) % this.slides.length;
};

Slideshow.prototype.play = function () {
    if (this.autoPlayTimer) {
        clearInterval(this.autoPlayTimer);
    }

    if (this.slides.length > 0 && this.pause !== true) {
        this.autoPlayTimer = setInterval(this.slideIterator.bind(this), this.slideSpeed);
    }
};

Slideshow.prototype.playTimerClear = function () {
    if (this.autoPlayTimer) {
        clearInterval(this.autoPlayTimer)
    }
};

Slideshow.prototype.pause = function () {
    this.playTimerClear();
    this.pause = true;
};

return Slideshow

})();

There is an error : Uncaught TypeError: Cannot read property 'length' of undefined at line 22.

I think it's because this changes, and it is not Slideshow anymore for some reason...

1 Answers1

0

Problem is that setInterval changes the scope so this will be window. You can fix it by binding.

this.autoPlayTimer = setInterval(this.slideIterator, this.slideSpeed);

to

this.autoPlayTimer = setInterval(this.slideIterator.bind(this), this.slideSpeed);

MDN bind()

epascarello
  • 204,599
  • 20
  • 195
  • 236