Search code examples
javascriptjqueryhtmlcssmaterialize

Materializecss v1.0.0 Carousel autoscroll / autoplay (no jquery)


How do you create an autoscroll feature for carousels in materializecss v1.0.0 without JQuery?

Currently materialize does not support an auto scroll or auto play feature. There are methods for calling next and prev, so there must be a way to set up an automatically scrolling carousel.


Solution

  • I wanted to post a solution that I think others will find useful. Here, I have created an autoscroll feature for carousels in materializecss v1.0.0 without the use of jquery.

    I personally think this is something that should be in as default in materializecss, but since it is not, I made this.

    You can also check it out here at https://codepen.io/tuffant21/pen/abOKPgO

    Would greatly appreciate a +1 :)

    window.onload = function() {
      initCarousel('.carousel', {
        fullWidth: true,
        indicators: true,
        autoScroll: 6000 // time in ms
      });
    }
    
    function initCarousel(elms, opts) {
      if (!window || !document) return null;
    
      const instances = M.Carousel.init(getElements(elms), opts);
    
      if (Array.isArray(instances)) {
        for (let i = 0; i < instances.length; ++i) {
          addAutoScroll(instances[i]);
        }
      } else {
        addAutoScroll(instances);
      }
    
      return instances;
    }
    
    function destroyCarousel(instances) {
      if (!window || !document) return null;
    
      if (Array.isArray(instances)) {
        for (let i = 0; i < instances.length; ++i) {
          removeAutoScroll(instances[i]);
          instances[i].destroy();
        }
      } else {
        removeAutoScroll(instances);
        instances.destroy();
      }
    }
    
    function addAutoScroll(instance) {
      if (!instance.options.autoScroll) return;
    
      instance.autoScrollIntervalId = window.setInterval(() => {
        instance.next();
      }, instance.options.autoScroll);
    
      instance.el.addEventListener("mouseover", carouselMouseOverTouchStart, {
        passive: true
      });
      instance.el.addEventListener("mouseleave", carouselMouseOutTouchEnd, {
        passive: true
      });
      instance.el.addEventListener("touchstart", carouselMouseOverTouchStart, {
        passive: true
      });
      instance.el.addEventListener("touchend", carouselMouseOutTouchEnd, {
        passive: true
      });
    }
    
    function removeAutoScroll(instance) {
      if (instance.autoScrollIntervalId) {
        window.clearInterval(instance.autoScrollIntervalId);
        instance.autoScrollIntervalId = undefined;
      }
    
      instance.el.removeEventListener("mouseover", carouselMouseOverTouchStart);
      instance.el.removeEventListener("mouseleave", carouselMouseOutTouchEnd);
      instance.el.removeEventListener("touchstart", carouselMouseOverTouchStart);
      instance.el.removeEventListener("touchend", carouselMouseOutTouchEnd);
    }
    
    function carouselMouseOverTouchStart() {
      const instance = M.Carousel.getInstance(this);
      if (!instance) return;
    
      if (instance.autoScrollIntervalId) {
        window.clearInterval(instance.autoScrollIntervalId);
        instance.autoScrollIntervalId = undefined;
      }
    }
    
    function carouselMouseOutTouchEnd() {
      const instance = M.Carousel.getInstance(this);
      if (!instance) return;
    
      if (!instance.autoScrollIntervalId) {
        instance.autoScrollIntervalId = window.setInterval(() => {
          instance.next();
        }, instance.options.autoScroll);
      }
    }
    
    // if searching for an element by id, insert a # in front of the passed in id
    function getElements(elms) {
      if (elms.charAt(0) === "#") {
        elms = elms.replace("#", "");
        return document.getElementById(elms);
      }
    
      return document.querySelectorAll(elms);
    }
    <!-- Compiled and minified CSS -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
    <!-- Compiled and minified JavaScript -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
    
    <!-- Take note of the no-autoinit class -->
    <!-- If you want M.AutoInit() to ignore a certain element, you can add the class .no-autoinit to the element and it will not be initialized by autoinit. -->
    <div class="container">
      <div class="carousel carousel-slider no-autoinit">
        <a class="carousel-item"><img src="https://lorempixel.com/800/400/food/1"></a>
        <a class="carousel-item"><img src="https://lorempixel.com/800/400/food/2"></a>
        <a class="carousel-item"><img src="https://lorempixel.com/800/400/food/3"></a>
        <a class="carousel-item"><img src="https://lorempixel.com/800/400/food/4"></a>
      </div>
    </div>