S
S
SongaerDev2019-08-23 00:17:18
JavaScript
SongaerDev, 2019-08-23 00:17:18

I'm learning OOP JavaScript. Method within a method?

Hello. I am slowly starting to delve into JavaScript OOP (in JS itself, too, relatively recently), I decided to write my own slider. The code itself:

window.addEventListener('DOMContentLoaded', () => {
  //slider
  let portfolioSlider = document.querySelector('.portfolio-slider__wrap'); //главный контейнер слайдера
  //Если слайдер есть на странице
  if (portfolioSlider) {
    class PortfolioSlider {
      constructor (autoSlide = 'auto') {
        let sliderItem    = portfolioSlider.querySelectorAll('.slider__item'); // получаем одиночные слайды
        this.numberSlides = sliderItem.length;
        this.autoSlide    = autoSlide;
      }

      //генерируем точки навигации
      createNavDots () {
        if (this.numberSlides !== 1) {
          let sliderDots = portfolioSlider.querySelector('.slider__dots'); //контейнер с точками навигации

          for (let i = 0; i < this.numberSlides; i++) {
            let singleDots = document.createElement('span');

            singleDots.classList.add('single-dot');
            if (i === 0) {
              singleDots.classList.add('active');
            }
            sliderDots.insertAdjacentElement('beforeend', singleDots);
          }
        }
      }

      //управление слайдами
      slidesNavigation () {
        if (this.numberSlides !== 1) {
          let sliderDots    = portfolioSlider.querySelectorAll('.single-dot'),
              sliderItems   = portfolioSlider.querySelector('.slider__items'),
              indexItemPrev = 0,
              indexItem     = 0,
              nextSlide     = portfolioSlider.querySelector('.next-slide'),
              prevSlide     = portfolioSlider.querySelector('.prev-slide'),
              slidePosition = 0;

          if (this.autoSlide === 'auto') {
            setInterval(() => {
              indexItem += 1;
              slidePosition += 100;

              if (indexItem > this.numberSlides-1 || slidePosition > (this.numberSlides-1) * 100) {
                indexItem = 0;
                slidePosition = 0;
              }

              sliderItems.style.transform = 'translateX(-'+ slidePosition +'%)';

              sliderDots[indexItemPrev].classList.remove('active');
              indexItemPrev = indexItem;
              sliderDots[indexItem].classList.add('active');
            }, 2000);
          }

          //отображаем полосы навигации
          nextSlide.style.display = 'block';
          prevSlide.style.display = 'block';

          //обрабатываем клик по точкам навигации
          sliderDots.forEach(function (item) {
            item.addEventListener('click', () => {
              let parentItem = item.parentNode;

              indexItem = Array.prototype.indexOf.call(parentItem.children, item);

              slidePosition = indexItem * 100;
              sliderItems.style.transform = 'translateX(-'+ slidePosition +'%)';

              sliderDots[indexItemPrev].classList.remove('active');
              indexItemPrev = indexItem;
              sliderDots[indexItem].classList.add('active');
            });
          });

          //обрабатываем клик по стрелкам вперед/назад
          prevSlide.addEventListener('click', () => {
            indexItem -= 1;
            slidePosition -= 100;

            if (indexItem < 0 || slidePosition < 0) {
              indexItem = this.numberSlides-1;
              slidePosition = (this.numberSlides-1) * 100;
            }
            console.log(slidePosition);

            sliderItems.style.transform = 'translateX(-'+ slidePosition +'%)';

            sliderDots[indexItemPrev].classList.remove('active');
            indexItemPrev = indexItem;
            sliderDots[indexItem].classList.add('active');
          });

          nextSlide.addEventListener('click', () => {
            indexItem += 1;
            slidePosition += 100;

            if (indexItem > this.numberSlides-1 || slidePosition > (this.numberSlides-1) * 100) {
              indexItem = 0;
              slidePosition = 0;
            }

            sliderItems.style.transform = 'translateX(-'+ slidePosition +'%)';

            sliderDots[indexItemPrev].classList.remove('active');
            indexItemPrev = indexItem;
            sliderDots[indexItem].classList.add('active');
          });
        }
      }
    }
    //создаем экземпляр слайдера
    const portfolioMainSlider = new PortfolioSlider('auto');
    portfolioMainSlider.createNavDots();
    portfolioMainSlider.slidesNavigation();
  }
});

Do not judge strictly, in JS quite recently, I implemented it as best I could (but, of course, I will not refuse constructive criticism) :) The question is the following. There is a slidesNavigation method , in which it tracks the click on the navigation buttons and switches slides depending on the index. Each click handler has a piece of view code:
sliderDots[indexItemPrev].classList.remove('active');
indexItemPrev = indexItem;
sliderDots[indexItem].classList.add('active');

This fragment is repeated in each handler and it would be logical to put it in a separate class method and call it inside the slidesNavigation method , but it seems impossible to do so.
Please help me to sort out this issue. Thanks in advance!

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
Viktor, 2019-08-23
@SongaerDev

In fact, everything is quite simple. There are two ways to go:
1) Create a function inside the method and call it. Simple and convenient way. The class is not cluttered and no need to create any parameters for the method

slidesNavigation() {
  // твой метод, в котором уже есть код
  ...

  // заменяешь повторяющийся фрагмент на вызов функции
  toggleDotClasses();

  // функция, в которую завёрнут часто повторяющийся фрагмент
  function toggleDotClasses() {
    sliderDots[indexItemPrev].classList.remove('active');
    indexItemPrev = indexItem;
    sliderDots[indexItem].classList.add('active');
  }
}

2) Create a new method in the class. This is worth doing if there is at least a suspicion that this method of yours may be required in other methods other than slidesNavigation
class PortfolioSlider {
  ...

  // новый метод класса. нижнее подчеркивание намекает на то, что метод как бы приватный (служебный)
  _toggleDotClasses(sliderDots, indexItemPrev, indexItem) {
    sliderDots[indexItemPrev].classList.remove('active');
    indexItemPrev = indexItem;
    sliderDots[indexItem].classList.add('active');
  }

  slidesNavigation () {
    this._toggleDotClasses(sliderDots, indexItemPrev, indexItem);
  }
}

In my opinion it is better to use the first option. In the current implementation of the class, the second option is not very convenient.

B
bini1988, 2019-08-24
@bini1988

As an option:

toggleActiveDot(activeIndex) {
    Array.from(sliderDots).forEach((dot, index) => {
       if (index === activeIndex) {
          dot.classList.add('active');
      } else {
          dot.classList.remove('active');
      } 
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question