variable not available outside my constructor

23 views Asked by At

I would like to make a simple carousel without libraries.

I defined a class but I can't access my variable outside of my constructor.

I use a script defer with my DOMContentLoaded event.

class Carousel {
    /**
     * @param {HTMLElement} element 
     * @param {Object} options.slidesToScroll Number of elements to slide 
     * @param {Object} options.slidesVisible Number of elements to display 
     */
    constructor (element, options = {}) {
        this.element = element
        this.options = Object.assign({}, {
            slidesToScroll: 1, 
            slidesVisible: 1
        }, options)

        let children = [].slice.call(element.children)

        let currentItem = 0

        this.root = this.createDivWithClass('carousel')
        this.container = this.createDivWithClass('carousel-container')
        this.root.appendChild(this.container)
        this.element.appendChild(this.root)
 
        this.items = children.map((child) => {
            let item = this.createDivWithClass('carousel-item')
            item.appendChild(child)
            this.container.appendChild(item)
            return item
        });
        this.setStyle()
        this.createNavigation()
    }

    /**
     * Applies the correct dimensions to the items in the carousel
     */
    setStyle () {
        let ratio = this.items.length / this.options.slidesVisible
        this.container.style.width = (ratio * 100) + "%"
        this.items.forEach(item => item.style.width = ((100 / this.options.slidesVisible) / ratio) + "%")
    }

    createNavigation () {
        let nextButton = this.createDivWithClass('carousel-next')
        let prevButton = this.createDivWithClass('carousel-prev')
        this.root.appendChild(nextButton)
        this.root.appendChild(prevButton)
        nextButton.addEventListener('click', this.next.bind(this))
        prevButton.addEventListener('click', this.prev.bind(this))
    }

    next () {
        this.goToItem(this.currentItem + this.options.slidesToScroll)
    }

    prev () {
        this.goToItem(this.currentItem - this.options.slidesToScroll)
    }

    /**
     * Moves the carousel to the targeted element
     * @param {number} index   
     */
    goToItem (index) {
        this.currentItem = index
        let translateX = index * (-100 / this.items.length)
        this.container.style.transform = 'translate3d(' + translateX + '%, 0, 0)'
        console.log("translateX", translateX);
        console.log("currentItem", this.currentItem);
        console.log("typeof(currentItem)", typeof(this.currentItem));
        console.log("typeof(index)", typeof(index));
        console.log("index", index);
    }

    /**
     * 
     * @param {string} className
     * @returns {HTMLElement} 
     */
    createDivWithClass (className) {
        let div = document.createElement('div')
        div.setAttribute('class', className)
        return div
    }
}

document.addEventListener('DOMContentLoaded', function () {
    new Carousel(document.querySelector('#carousel1'), {
        slidesVisible: 3,
        slidesToScroll: 1
    })
})

Results of my logs :

translateX NaN
currentItem NaN
typeof(currentItem) number
typeof(index) number
index NaN

In the DOM, I get this :

<div id="carousel1">
    <div class="carousel">
        <div class="carousel-container" style="width: 166.667%">
            <div class="carousel-item" style="width: 20%"></div>
            <div class="carousel-item" style="width: 20%"></div>
            <div class="carousel-item" style="width: 20%"></div>
            <div class="carousel-item" style="width: 20%"></div>
            <div class="carousel-item" style="width: 20%"></div>
        </div>
        <div class="carousel-next"></div>
        <div class="carousel-prev"></div>
    </div>
</div>

When I give a value to my currentItem, I can see my function works :

    goToItem () {
        let index = 1
        let translateX = index * (-100 / this.items.length)
        this.container.style.transform = 'translate3d(' + translateX + '%, 0, 0)'

        console.log("translateX", translateX);
    }

Results of my logs :

translateX -20

I should have the index incremented with each click.

Do you know why my variable is NaN ?

2

There are 2 answers

1
Phillipe Alakša On

Maybe try declaring the function at the start instead of the end.

0
kevkevkev On

I finally managed to figure out where the error came from. it was basic, i was trying to access a variable out of scope... So I replaced let with this to give it a call reference.