Two carousels in one page

Viewed 49

I am trying to put carousels in my page, and code below from [this page][1] works great for one carousel in a page but when I try to put two carousels in one page, it doesn't work.

I couldn't figure out how I can make it work as I am a beginner with jQuery. Does anyone have any idea how I can make it work?

$(function() {
  var carousel = $('.carousel ul');
  var carouselChild = carousel.find('li');
  var clickCount = 0;

  itemWidth = carousel.find('li:first').width() + 1; //Including margin

  //Set Carousel width so it won't wrap
  carousel.width(itemWidth * carouselChild.length);

  //Place the child elements to their original locations.
  refreshChildPosition();

  //Set the event handlers for buttons.
  $('.btnNext').click(function() {
    clickCount++;

    //Animate the slider to left as item width 
    carousel.finish().animate({
      left: '-=' + itemWidth
    }, 300, function() {
      //Find the first item and append it as the last item.
      lastItem = carousel.find('li:first');
      lastItem.remove().appendTo(carousel);
      lastItem.css('left', ((carouselChild.length - 1) * (itemWidth)) + (clickCount * itemWidth));
    });
  });

  $('.btnPrevious').click(function() {
    clickCount--;
    //Find the first item and append it as the last item.
    lastItem = carousel.find('li:last');
    lastItem.remove().prependTo(carousel);

    lastItem.css('left', itemWidth * clickCount);
    //Animate the slider to right as item width 
    carousel.finish().animate({
      left: '+=' + itemWidth
    }, 300);
  });

  function refreshChildPosition() {
    carouselChild.each(function() {
      $(this).css('left', itemWidth * carouselChild.index($(this)));
    });
  }

  function refreshChildPositionNext() {
    carouselChild.each(function() {
      leftVal = parseInt($(this).css('left'));
    });
  }
});
.carousel {
  padding-top: 20px;
  width: 357px;
  overflow: hidden;
  height: 50px;
  position: relative;
}

.carousel ul {
  position: relative;
  list-style: none;
  list-style-type: none;
  margin: 0;
  height: 50px;
  padding: 0;
}

.carousel ul li {
  position: absolute;
  height: 25px;
  width: 50px;
  float: left;
  margin-right: 1px;
  background: #f2f2f2;
  text-align: center;
  padding-top: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<a href="javascript:void(0);" class="btnPrevious">Previous</a>
<a href="javascript:void(0);" class="btnNext">Next</a>
<div class="carousel">
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
    <li>10</li>
    <li>11</li>
    <li>12</li>
    <li>13</li>
    <li>14</li>
  </ul>
</div>

http://jsfiddle.net/artuc/rGLsG/3/

1 Answers

The issue is because the selectors are working in a manner which would select all .carousel instances, no matter how many there are. To fix this you would need to loop through each instance and then use DOM traversal to find the related elements for that specific carousel only.

It would also make sense to convert this to a jQuery extension which you can call on the elements which contain the carousels, like this:

$(function() {
  $.fn.carousel = function() {
    $(this).each(function() {
      var $container = $(this);
      var $carousel = $container.find('.carousel ul');
      var $carouselChild = $carousel.find('li');
      var $prev = $container.find('.btnPrevious');
      var $next = $container.find('.btnNext');
      var clickCount = 0;

      itemWidth = $carousel.find('li:first').width() + 1;
      $carousel.width(itemWidth * $carouselChild.length);
      refreshChildPosition();

      $next.click(function() {
        clickCount++;

        $carousel.finish().animate({
          left: '-=' + itemWidth
        }, 300, function() {
          lastItem = $carousel.find('li:first');
          lastItem.remove().appendTo($carousel);
          lastItem.css('left', (($carouselChild.length - 1) * (itemWidth)) + (clickCount * itemWidth));
        });
      });

      $prev.click(function() {
        clickCount--;
        lastItem = $carousel.find('li:last');
        lastItem.remove().prependTo($carousel);
        lastItem.css('left', itemWidth * clickCount);
        $carousel.finish().animate({
          left: '+=' + itemWidth
        }, 300);
      });

      function refreshChildPosition() {
        $carouselChild.each(function() {
          $(this).css('left', itemWidth * $carouselChild.index($(this)));
        });
      }

      function refreshChildPositionNext() {
        $carouselChild.each(function() {
          leftVal = parseInt($(this).css('left'));
        });
      }
    });
  }
  
  $('.carousel-container').carousel();
});
.carousel {
  padding-top: 20px;
  width: 357px;
  overflow: hidden;
  height: 50px;
  position: relative;
}

.carousel ul {
  position: relative;
  list-style: none;
  list-style-type: none;
  margin: 0;
  height: 50px;
  padding: 0;
}

.carousel ul li {
  position: absolute;
  height: 25px;
  width: 50px;
  float: left;
  margin-right: 1px;
  background: #f2f2f2;
  text-align: center;
  padding-top: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="carousel-container">
  <a href="#" class="btnPrevious">Previous</a>
  <a href="#" class="btnNext">Next</a>
  <div class="carousel">
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
      <li>6</li>
      <li>7</li>
      <li>8</li>
      <li>9</li>
      <li>10</li>
      <li>11</li>
      <li>12</li>
      <li>13</li>
      <li>14</li>
    </ul>
  </div>
</div>

<div class="carousel-container">
  <a href="#" class="btnPrevious">Previous</a>
  <a href="#" class="btnNext">Next</a>
  <div class="carousel">
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
      <li>6</li>
      <li>7</li>
      <li>8</li>
      <li>9</li>
      <li>10</li>
      <li>11</li>
      <li>12</li>
      <li>13</li>
      <li>14</li>
    </ul>
  </div>
</div>

Related