Flex Slider - How to add same controls for two sli

2019-01-17 23:55发布

问题:

I am using Flex slider for one project. I need to control two sliders on one page with same controls.

One part is main slider that will show images, and the second one is text (in this case it will be taken from "the_excerpt" in WP ).

Basically, this is the code I am using to call two slides on one page:

  $(window).load(function() {
    $('#main-slider').flexslider({
      animation: 'slide',
      controlsContainer: '.flex-container'
    });

    $('#secondary-slider').flexslider();
  });

Now, I need to "connect" both of them to same controls, so when I click on arrow, it will slide/fade both of them.

回答1:

You could accomplish what you're trying to do by ditching the controlsContainer setting and creating your own navigation that you then link to both sliders. Here's an idea of how (please note it's untested)

Your markup would look something like this. Note the rel attribute on the links - we'll use them below. Also note that the values start from 0 - this matches the values for the slides (e.g. the first slide is 0, the second is 1 etc).

<a rel="0" class="slide_thumb" href="#">slide link 1</a>
<a rel="1" class="slide_thumb" href="#">slide link 2</a>
<a rel="2" class="slide_thumb" href="#">slide link 3</a>
<a rel="3" class="slide_thumb" href="#">slide link 3</a>

<div id="main-slider" class="flexslider">
<ul class="slides">
    <li>
        <img src="image1.jpg" />
    </li>
    <li>
        <img src="image2.jpg" />
    </li>
    <li>
        <img src="image3.jpg" />
    </li>
    <li>
        <img src="image4.jpg" />
    </li>
</ul>
</div>

<div id="secondary-slider" class="flexslider">
<ul class="slides">
    <li>
        <p>Text 1</p>
    </li>
    <li>
        <p>Text 2</p>
    </li>
    <li>
        <p>Text 3</p>
    </li>
    <li>
        <p>Text 4</p>
    </li>
</ul>

Then you set up the call to flexslider

<script type="text/javascript" charset="utf-8">
jQuery(document).ready(function($) {

$('#main-slider').flexslider({
    animation: "slide",
    slideToStart: 0,
    start: function(slider) {
        $('a.slide_thumb').click(function() {
            $('.flexslider').show();
            var slideTo = $(this).attr("rel")//Grab rel value from link;
            var slideToInt = parseInt(slideTo)//Make sure that this value is an integer;
            if (slider.currentSlide != slideToInt) {
                slider.flexAnimate(slideToInt)//move the slider to the correct slide (Unless the slider is also already showing the slide we want);
            }
        });
    }

});

$('#secondary-slider').flexslider({
    animation: "slide",
    slideToStart: 0,
    start: function(slider) {
        $('a.slide_thumb').click(function() {
            $('.flexslider').show();
            var slideTo = $(this).attr("rel")//Grab rel value from link;
            var slideToInt = parseInt(slideTo)//Make sure that this value is an integer;
            if (slider.currentSlide != slideToInt) {
                slider.flexAnimate(slideToInt)//move the slider to the correct slide (Unless the slider is also already showing the slide we want);
            }
        });
    }

});

});
</script>

Basically both sliders are controlled by the same set of navigation links. Think this should get you moving in the right direction but shout if you need anything explained.



回答2:

For Flexslider 2, you can use sync: "selector" option. Just set one of the sliders' controlNav: false.

$(window).load(function() {
    $('#main-slider').flexslider({
        animation: 'slide',
        controlNav: true,
        sync: '#secondary-slider'
    });

    $('#secondary-slider').flexslider({
        controlNav: false
    });
});


回答3:

So, I have been having the same issue and it can be a real drag... But I have come to a quick solution that is easy as pie. This will work for 1 child or a hundred children controlled by on parent flexslider. Works for all actions. Hopefully I can talk them into fixing this and allowing an array of jquery objects for there sync method.

<div id="main-slider" class="flexslider">
  <ul class="slides">
    <li><img src="image1.jpg" /></li>
    <li><img src="image2.jpg" /></li>
    <li><img src="image3.jpg" /></li>
    <li><img src="image4.jpg" /></li>
  </ul>
</div>

<div class="flexslider_children">
  <ul class="slides">
    <li><p>Text 1</p></li>
    <li><p>Text 2</p></li>
    <li><p>Text 3</p></li>
    <li><p>Text 4</p></li>
  </ul>
</div>

<div class="flexslider_children">
  <ul class="slides">
    <li><p>Text 1</p></li>
    <li><p>Text 2</p></li>
    <li><p>Text 3</p></li>
    <li><p>Text 4</p></li>
  </ul>
</div>

Then for your javascript just run this.

/** 
* Create the children flexsliders. Must be array of jquery objects with the
* flexslider data. Easiest way is to place selector group in a var.
*/
var children_slides = $('.flexslider_children').flexslider({
  'slideshow': false, // Remove the animations
  'controlNav' : false // Remove the controls
}); 

/** 
* Set up the main flexslider
*/
$('.flexslider').flexslider({
  'pauseOnHover' : true,
  'animationSpeed': 2000,
  'slideshowSpeed': 5000,
  'initDelay': 3000,
  // Call the update_children_slides which itterates through all children slides 
  'before' : function(slider){ // Hijack the flexslider
    update_children_slides(slider.animatingTo);
  }   
}); 

/** 
* Method that updates children slides
* fortunately, since all the children are not animating,
* they will only update if the main flexslider updates. 
*/
function update_children_slides (slide_number){
  // Iterate through the children slides but not past the max
  for (i=0;i<children_slides.length;i++) {
    // Run the animate method on the child slide
    $(children_slides[i]).data('flexslider').flexAnimate(slide_number);
  }   
}

Hope this helps!! Please note I added this cause it closely resembles what i was trying to do, Seems like I am not the only one looking to use multiple syncs in flexslider.



回答4:

I want to confirm that MrBandersnatch's solution works. I'm posting my alterations of his code below to show a variation of his work.

/** 
* Create the children flexsliders. Must be array of jquery objects with the
* flexslider data. Easiest way is to place selector group in a var.
*/
var children_slides = $('.flexslider_children').flexslider({
    slideshow: false, // Remove the animations
    controlNav : false, // Remove the controls
    animationSpeed: 1200,
    itemWidth: 175,
    itemMargin: 20,
    animation: 'linear',
    easing: 'swing',
    animationLoop: false,
    minItems: getGridSize(), // use function to pull in initial value
    maxItems: getGridSize()
}); 


/** 
* Set up the main flexslider
*/
$('#flexslider_index_band_1').flexslider({
    pauseOnHover : true,
    animationSpeed: 1200,
    slideshow: false,
    initDelay: 3000,
    directionNav: true,
    animation: 'linear',
    easing: 'swing',
    animationLoop: false,
    controlsContainer: '.paginated_nav',
    directionNav: true,
    prevText: '',
    nextText: '',
    itemWidth: 175,
    itemMargin: 20,
    sync: '#flexslider_index_band_2',
    minItems: getGridSize(), // use function to pull in initial value
    maxItems: getGridSize(), // use function to pull in initial value
    // Call the update_children_slides which itterates through all children slides 
    before : function(slider){ // Hijack the flexslider
        update_children_slides(slider.animatingTo);
    }   
}); 

/** 
* Method that updates children slides
* fortunately, since all the children are not animating,
* they will only update if the main flexslider updates. 
*/
function update_children_slides (slide_number){
    // Iterate through the children slides but not past the max
    for (i=0;i<children_slides.length;i++) {
    // Run the animate method on the child slide
    $(children_slides[i]).data('flexslider').flexAnimate(slide_number);
    }   
}

});



回答5:

One solution I found was to create you own custom banner navigation. Position it and style it however you like. The only important thing is having a way to target it. In this example I used an ID of slider-next and slider-prev.

<ul>
  <li><a id="slider-next" href="#">Next</a></li>
  <li><a id="slider-prev" href="#">Prev</a></li>
</ul>

Now, create two flexer sliders and position them however you would like in your css. I will title my main banner .flexslider and my caption .captions.

<div class="flexslider">
  <ul class="slides">
    <li><img src="/assets/images/banner-example.png" width="893" height="377"></li>
    <li><img src="/assets/images/banner-example-2.png" width="893" height="377" /></li>
    <li><img src="/assets/images/banner-example-3.png" width="893" height="377" /></li>
    <li><img src="/assets/images/banner-example-4.png" width="893" height="377" /></li>
  </ul>
</div>
<!-- Some other place in the code -->
<div class="captions">
  <ul id="info" class="slides">
    <li>
      <h2>Example Banner 1</h2>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
      <a href="read-more">Read More</a>
    </li>
    <li>
      <h2>Example Banner 2</h2>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
      <a href="read-more">Read More</a>
    </li>
    <li>
      <h2>Example Banner 3</h2>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
      <a href="read-more">Read More</a>
    </li>
    <li>
      <h2>Example Banner 4</h2>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
      <a href="read-more">Read More</a>
    </li>
  </ul>
</div>

Now for the simple magic to make it work. Activate both slides in your javascript file and hide the banner and caption's nav controls in the css. That way your custom navigation will be the only controls visible. Then, just create a function to trigger both the slider and caption's control navs on click. Example down below. The .trigger jQuery function is what does the wizardry here. Check out its documentation here: http://api.jquery.com/trigger/

//Load slider after .ready()
$(window).load(function(){

    //Activate Both Banner and Caption slides
    $('.flexslider').flexslider({
        controlNav: false,
    });

    $('.captions').flexslider({
        controlNav: false,
    });

    //Sink Control Navs
    $('#slider-next').click(function(){
        $('.flexslider .flex-next').trigger('click');
        $('.captions .flex-next').trigger('click');
    });

    $('#slider-prev').click(function(){
        $('.flexslider .flex-prev').trigger('click');
        $('.captions .flex-prev').trigger('click');
    })
});