xbase-2.x-dev/js/carousel-init.js

js/carousel-init.js
(function () {

  /**
   * Return element preset.
   */
  function getElementPresetName(element) {
    var presetName;

    // Get preset name
    element.classList.forEach(className => {
      const presetMatches = className.match(/^carousel-preset-(.+)$/);
      if (presetMatches) {
        presetName = Drupal.camelize(presetMatches[1]);
        return false;
      }
    });

    return presetName;
  }

  /**
   * Wrap all children to new element.
   *
   * Example before:
   *   <div class="parent">
   *     <div class="child"></div>
   *     <div class="child"></div>
   *   </div>
   * After:
   *   <div class="parent">
   *     <div class="inner">
   *       <div class="child"></div>
   *       <div class="child"></div>
   *     </div>
   *   </div>
   */
  function wrapChildren(element, wrapperEl) {
    if (!wrapperEl) {
      wrapperEl = document.createElement('div');
    }

    while (element.children.length) {
      wrapperEl.append(element.children[0]);
    }

    element.append(wrapperEl);

    return wrapperEl;
  }

  /**
   * Create element and append to owner.
   */
  function createElementAndAppendTo(tagName, className, ownerEl) {
    const element = document.createElement(tagName);

    if (className) {
      if (Array.isArray(className)) {
        element.classList.add(...className);
      }
      else {
        element.classList.add(className);
      }
    }

    if (ownerEl) {
      ownerEl.append(element);
    }

    return element;
  }

  /**
   * Create required elements and add classes.
   */
  function preprocessCarouselElement(carouselEl, options) {
    carouselEl.classList.add('carousel', 'swiper-container');

    // Create swiper element
    const swiperEl = wrapChildren(carouselEl);
    swiperEl.classList.add('swiper');

    // Add "swiper-slide" class to slides
    for (const slideEl of swiperEl.children) {
      slideEl.classList.add('swiper-slide');
    }

    // Create navigation elements outside swiper element
    if (options.navigation) {
      if (typeof options.navigation == 'boolean') {
        options.navigation = {};
      }
      if (!options.navigation.el) {
        // options.navigation.el it's custom option
        options.navigation.el = createElementAndAppendTo('div', 'swiper-navigation', carouselEl);
      }
      if (!options.navigation.prevEl) {
        options.navigation.prevEl = createElementAndAppendTo('div', ['swiper-navigation-button', 'swiper-button-prev'], options.navigation.el);
      }
      if (!options.navigation.nextEl) {
        options.navigation.nextEl = createElementAndAppendTo('div', ['swiper-navigation-button', 'swiper-button-next'], options.navigation.el);
      }
    }

    // Create pagination element outside swiper element
    if (options.pagination) {
      if (typeof options.pagination == 'boolean') {
        options.pagination = {};
      }
      if (!options.pagination.el) {
        options.pagination.el = createElementAndAppendTo('div', 'swiper-pagination', carouselEl);
      }
    }
  }

  /**
   * Create carousel.
   */
  Drupal.carousel = function (carouselEl, presetName = '', options = {}) {
    // Error handlers
    if (!presetName) {
      console.error('Carousel preset name not found.');
      return false;
    }
    if (!Drupal.carouselPresets) {
      console.error('Carousel presets not exist.');
      return false;
    }
    if (!Drupal.carouselPresets[presetName]) {
      console.error('Carousel preset "' + presetName + '" not exist.');
      return false;
    }
    if (!carouselEl) {
      console.error('Carousel element not exist.');
      return false;
    }

    // Merge options
    options = {createElements: true, ...Drupal.carouselPresets[presetName], ...options};

    // Create required elements and add classes
    if (options.createElements) {
      preprocessCarouselElement(carouselEl, options);
    }

    // Fix bug when not work slidesPerGroupAuto:true
    // Set slidesPerGroup option from css variable
    if (options.slidesPerGroupAuto) {
      options.slidesPerGroup = Drupal.getCssVariable('--carousel-slides-count', carouselEl, 1, 'int');
    }

    const swiperEl = carouselEl.querySelector('.swiper');
    const swiper = new Swiper(swiperEl, options);

    // Fix bug when not work slidesPerGroupAuto:true
    if (options.slidesPerGroupAuto) {
      /** @param {Swiper} swiper */
      swiper.on('beforeResize', (swiper) => {
        swiper.params.slidesPerGroup = Drupal.getCssVariable('--carousel-slides-count', swiper.el, 1, 'int');
      });
    }
  }

  /**
   * Drupal behaviors.
   */
  Drupal.behaviors.carousel = {
    attach: function (context, settings) {
      if (context.tagName == 'SCRIPT' || !window.Swiper) {
        return;
      }

      once('carousel', '.carousel', context).forEach(carouselEl => {
        Drupal.carousel(carouselEl, getElementPresetName(carouselEl));
      });
    }
  };

})();

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc