El otro dÃa desarrollando la web para un cliente me topé con una incompatibilidad que no conocÃa con la popular librerÃa para crear carruseles jCarousel. Os explico el proceso. QuerÃa implementar una paginación inline mediante la ocultación de elementos. Es decir, mostraba cuatro elementos y cuando el usuario pulsará el botón “Ver más” se mostrarÃan otros cuatro, y asà sucesivamente. Oculté dichos elementos con el ya clásico display:none de CSS. Cual fue mi sorpresa que, cuando hice estos carruseles ocultos otra vez visibles vi que la funcionalidad de carrusel se habÃa perdido. Resumiendo, cada vez que quitaba el display:none de los elementos, estos no volvÃan a contar con la función que les otorgaba jCarousel.
Tras investigar y tras realizar unas cuantas pruebas pude dar con lo que estaba sucediendo. Y es que el problema no estaba en el display:none en sà (hice pruebas con la propiedad visibility de CSS e incluso metiendo dichos elementos en un wrapper), si no en que se debe recargar el elemento jCarousel cada vez que lo hacemos visible. Para ello incluso existe una función que te permite recargar el elemento.
Para que lo entendáis mejor vamos con un contexto claro. Este serÃa el código del markup de nuestro elemento. He puesto el CSS como parámetro del HTML para que sea más explicativo.
<script type="text/javascript" src="/js/jquery.js"></script> <script type="text/javascript" src="/js/jquery.jcarousel.min.js"></script> <div class="jcarousel-wrapper" id="jcarousel-wrapper" class="display:none;"> <a href="#" class="jcarousel-control-prev"><</a> <div class="jcarousel" id="jcarousel-demo"> <ul> <li class="item"> <h3>Elemento 1</h3> </li> <li class="item"> <h3>Elemento 2</h3> </li> <li class="item"> <h3>Elemento 3</h3> </li> <li class="item"> <h3>Elemento 4</h3> </li> <li class="item"> <h3>Elemento 5</h3> </li> </ul> </div> <a href="#" class="jcarousel-control-next">></a> </div> <span onclick="showCarousel()" id="btnshow" class="btn">Ver mas</span> <script> //Inicializamos nuestro carrusel var jcarouseldemo = $('#jcarousel-demo'); jcarouseldemo .on('jcarousel:reload jcarousel:create', function () { var carousel = $(this), width = carousel.innerWidth(); if (width >= 600) { width = width / 4; } else if (width >= 350) { width = width / 1; } carousel.jcarousel('items').css('width', Math.ceil(width) + 'px'); }) .jcarousel({ wrap: 'circular' }); $('.jcarousel-control-prev') .jcarouselControl({ target: '-=1' }); $('.jcarousel-control-next') .jcarouselControl({ target: '+=1' }); //Función para mostrar el carrusel function showCarousel(){ if (document.getElementById('jcarousel-wrapper')){ document.getElementById('jcarousel-wrapper').style.display = ''; } } </script>
Si dejamos esto asÃ, verás que al hacer visible el carrusel no funciona. Es decir, se muestran los elementos y tal pero no cuenta con la tÃpica función de carrusel en la que puedes pasar los elementos que la integran a placer mediante las flechas.
Como he comentado antes, para que funcione el carrusel de jCarousel hay que volver a recargar el elemento mediante el método reload de la librerÃa. Por lo tanto, habrÃa que añadir en la función showCarousel(), debajo de la lÃnea document.getElementById('jcarousel-wrapper').style.display = ''; este código:
jcarouseldemo.jcarousel('reload');
El código completo serÃa este:
<script type="text/javascript" src="/js/jquery.js"></script> <script type="text/javascript" src="/js/jquery.jcarousel.min.js"></script> <div class="jcarousel-wrapper" id="jcarousel-wrapper" class="display:none;"> <a href="#" class="jcarousel-control-prev"><</a> <div class="jcarousel" id="jcarousel-demo"> <ul> <li class="item"> <h3>Elemento 1</h3> </li> <li class="item"> <h3>Elemento 2</h3> </li> <li class="item"> <h3>Elemento 3</h3> </li> <li class="item"> <h3>Elemento 4</h3> </li> <li class="item"> <h3>Elemento 5</h3> </li> </ul> </div> <a href="#" class="jcarousel-control-next">></a> </div> <span onclick="showCarousel()" id="btnshow" class="btn">Ver mas</span> <script> //Inicializamos nuestro carrusel var jcarouseldemo = $('#jcarousel-demo'); jcarouseldemo .on('jcarousel:reload jcarousel:create', function () { var carousel = $(this), width = carousel.innerWidth(); if (width >= 600) { width = width / 4; } else if (width >= 350) { width = width / 1; } carousel.jcarousel('items').css('width', Math.ceil(width) + 'px'); }) .jcarousel({ wrap: 'circular' }); $('.jcarousel-control-prev') .jcarouselControl({ target: '-=1' }); $('.jcarousel-control-next') .jcarouselControl({ target: '+=1' }); //Función para mostrar el carrusel function showCarousel(){ if (document.getElementById('jcarousel-wrapper')){ document.getElementById('jcarousel-wrapper').style.display = ''; jcarouseldemo.jcarousel('reload'); } } </script>
Ya sabéis, si alguna vez tenéis problemas al hacer visible un carrusel de jCarousel mediante display:none, recordad que debéis recargarlo.