Control BX Slider from outside of function

1k views Asked by At

I have multiple BX Sliders on a page. I don't want to have to give each one an explicit ID in the JavaScript (as the documentation suggests) as there could be an unknown number of sliders. Each carousel has an ID in the markup.

The slider also changes configuration at a certain breakpoints.

I want to be able to tell a slider to go to a certain slide on page load (something like $('#slider1').goToSlide(2) ).

However the .goToSlide() method is not exposed like that as it hasn't been assigned to that ID (only the class .js-carousel).

So how can I achieve this?

$ ->

  $('.js-carousel').each ->

    # Flags and selector cachine
    id = '#' + $(this).attr('id')
    sliderLoaded = false
    $slider = $( id )
    $wrapper = $slider.closest('.js-carousel-wrapper')
    $body = $('body')

    # Load different options based on the breakpoint
    sliderOptions = ( breakpoint ) ->
      switch breakpoint
        when 'large'
          bxLargeOptions =
            mode: 'fade'
            pagerCustom: id + '_pager'
            controls: false
            video: true
            adaptiveHeight: true
            # captions: true
            onSliderLoad: onSliderLoad

        when 'multi'
          bxMultiSmallOptions =
            controls: false
            minSlides: 2
            maxSlides: 6
            slideWidth: 128
            slideMargin: 0
            onSliderLoad: onSliderLoad
            infiniteLoop: false
            pager: false

        else
          bxSmallOptions =
            pagerCustom: '#pager'
            controls: false
            easing: 'cubic-bezier(0.645, 0.045, 0.355, 1.000)'
            video: true
            adaptiveHeight: true
            # captions: true
            onSliderLoad: onSliderLoad

    # Call on every slider load event
    onSliderLoad = ->

      # Set a flag
      sliderLoaded = true

      # get the custom next control
      sliderNext =
        $wrapper.find('.js-carousel-next')

      # Get the custom prev control
      sliderPrev =
        $wrapper.find('.js-carousel-prev')

      # Add active class to show controls
      $wrapper.addClass('is-active')

    # Return the slider type or false
    sliderType = ( type ) ->
      if $slider.data('carousel-type') == type
        return true
      else
        return false

    # Init or reload the slider
    slider = ( option, reload ) ->
      if reload
        $slider.reloadSlider sliderOptions( option )
      else
        $slider.bxSlider sliderOptions( option )

    # Load different sliders for small screens
    enquire.register "screen and (max-width:767px)",
      match: ->
        if !sliderType( 'multi' )
          if !sliderLoaded
            slider()
          else
            slider( false, true )
        else
          if !sliderLoaded
            slider( 'multi' )
          else
            slider( 'multi', true )

      # Destroy multi sliders at larger screen sizes
      unmatch: ->
        if sliderType( 'multi' )
          $slider.destroySlider()

    # Load different sliders for large screens
    enquire.register "screen and (min-width:768px)",
      match: ->
        if !sliderType( 'multi' )
          if !sliderLoaded
            slider('large')
          else
            slider('large', true)

    # Custom slider controls
    $wrapper.on 'click', '.js-carousel-control', (e) ->

      # Prevent normal behaviour in case it's a link
      # Although it should be a <button>
      e.preventDefault()

      # Get the direction stored in the data attribute
      slide = $(this).data().slide

      # Move the carousel
      # Default is to move to a specific slide number
      switch slide
        when 'prev' then $slider.goToPrevSlide()
        when 'next' then $slider.goToNextSlide()
        else $slider.goToSlide slide
1

There are 1 answers

1
Ahmed Nuaman On BEST ANSWER

So I've had a play, it just takes a little bit of fun to get it to work. Say this is your HTML:

<h3>Slideshow 1</h3>
<ul id="slider1" class="slider">
  <li><img src="http://bxslider.com/images/730_200/hill_trees.jpg" /></li>
  <li><img src="http://bxslider.com/images/730_200/me_trees.jpg" /></li>
  <li><img src="http://bxslider.com/images/730_200/houses.jpg" /></li>
</ul>

<h3>Slideshow 2</h3>
<ul id="slider2" class="slider">
  <li><img src="http://bxslider.com/images/730_200/tree_root.jpg" /></li>
  <li><img src="http://bxslider.com/images/730_200/trees.jpg" /></li>
  <li><img src="http://bxslider.com/images/730_200/hill_road.jpg" /></li>
</ul>

<h3>Slideshow 3</h3>
<ul id="slider3" class="slider">
  <li><img src="http://bxslider.com/images/730_200/tree_root.jpg" /></li>
  <li><img src="http://bxslider.com/images/730_200/trees.jpg" /></li>
  <li><img src="http://bxslider.com/images/730_200/hill_road.jpg" /></li>
</ul>

And this is your JS:

var sliders = [];

$('.slider').each(function () {
    sliders.push($(this).bxSlider({
      mode: 'fade',
      auto: true,
      autoControls: true,
      pause: 2000
    }));
});

sliders[1].goToSlide(1);

The trick is to get into a loop before you init each slider, then you have a reference to each slider, allowing you to pick one and access its APIs. See this example: http://jsfiddle.net/wosszb0w/3/