Search code examples
javascriptjqueryowl-carousel-2

owl carousel circular progress bar with classyloader gives a getContext error


I'm trying to create a circular progress bar around dots in owl carousel and ClassyLoader (https://andy.su/classyloader/). All fine but I got stuck with this error Cannot read property 'getContext' of undefined.

HTML

<div class="header-slider">
  <div class="header-slider-1">
    some slider content
  </div><!-- .header-slider-1 -->

  <div class="header-slider-2">
   some slider content
  </div><!-- .header-slider-2 -->

</div><!-- .header-slider -->

<div class="owl-dots" id="owldots">
  <div class="owl-dot"><canvas class="loader"></canvas><span></span></div>
  <div class="owl-dot"><canvas class="loader"></canvas><span></span></div>
</div>

JS

<script type="text/javascript">
  /* ------------------------- Owl settings -------------------------- */
  jQuery(function($){
    $(document).ready(function() {
      var timeout = 5000;
      var owl = $('.header-slider').owlCarousel({
          items: 1,
          dots: true,
          nav: false,
          loop:true,
          autoplay: true,
          autoplayTimeout: timeout,
          dotsContainer: '#owldots',
          onChanged: function () {
              $(function() {
                  var loader = $('.header-slider .owl-dot.active .loader').ClassyLoader({
                      width: 60,
                      height: 60,
                      percentage: 100,
                      speed: 20,
                      animate: true,
                      showRemaining: false,
                      showText: false,
                      diameter: 20,
                      lineColor: 'rgba(245,206,12,1)',
                      lineWidth: 2
                  });
              })
          }
      });
    });
  });
</script>

Any idea how can I get this working?


Solution

  • There are several problems with your code, but the most important is: ClassyLoader must be instancied on a canvas, from the page you linked:

    Next, you create the canvas element on which you want to trigger the plugin.

    Also as I stated in a comment, $(function() { ... }); is an alias to $(document).ready(function() { ... });. And because in your code $ is an alias to jQuery, it can be simplified. I personnally prefer document ready syntax, it's more evident what it does for future readers.

    NOTE: you'll see in the corrected codepen that you will probably have additional trouble with the CSS for your slides (they are not showing, probably conflict with owl carousel styles). I arbitrarily chose to set the canvas to fixed because it has to be a separate element and this will make it show upon the slides, but that can be improved. Note also that you need to use owl version 2 because of your syntax (changed your pen settings) and I directly copied ClassyLoader code because it doesn't work from filebin.

    corrected code:

    HTML:

    <canvas class="header-loader"></canvas>
    <div class="header-slider">
      <div class="header-slider-1">
        <p>some slider content 1</p>
      </div><!-- .header-slider-1 -->
    
      <div class="header-slider-2">
        <p>some slider content 2</p>
      </div><!-- .header-slider-2 -->
    </div><!-- .header-slider -->
    
    <div class="owl-dots" id="owldots">
      <div class="owl-dot"><canvas class="loader"></canvas><span></span></div>
      <div class="owl-dot"><canvas class="loader"></canvas><span></span></div>
    </div>
    

    JS:

    $(document).ready(function() { //you can also use "$(function() {" instead
      var timeout = 5000;
      var owl = $('.header-slider').owlCarousel({
        items: 1,
        dots: true,
        nav: false,
        loop:true,
        autoplay: true,
        autoplayTimeout: timeout,
        dotsContainer: '#owldots',
        onChanged: function () {
          //don't use "$(function() {" here!
          var loader = $('.header-loader').ClassyLoader({ //changed the class
            width: 60,
            height: 60,
            percentage: 100,
            speed: 20,
            animate: true,
            showRemaining: false,
            showText: false,
            diameter: 20,
            lineColor: 'rgba(245,206,12,1)',
            lineWidth: 2
          });
        }
      });
    });