0

I have this slider that indicates what slides is currently on by using .prev .next jquery to pass the class active in order show or indicate what slide is currently on.

Below is the code that produces that function. It looks for the current sibling that has the class active then passes it to the previous or next sibling.

//Slider Directional Controls
$('.buttons .prev').on('click', function() {
    if( position > 0 ) { 
        position--;
        $('.program-slider .slides').css({'right': position * programSliderWidth }); // -- CHANGE 3 --
        $('.navigation .controls').find('li.active').removeClass('active').prev('li').addClass('active');

    }
});

$('.buttons .next').on('click', function() {
    if( position < totalSlides - 1 ) { 
         position++;
          $('.program-slider .slides').css({'right': position * programSliderWidth});   
          $('.navigation .controls').find('li.active').removeClass('active').next('li').addClass('active');

      }
});

What if I want to reset the functionality? Basically remove the class active from its current sibling and place it on the first sibling to indicate it is the first slide being shown.

This is the code that I have created but seems to be working but when I clicked on the directional controls on the slider, it doesn't pass the class active to the next sibling. The way I reset the functional is by using $(window).on('resize', function(){})

//Add Class active on Start
$('.navigation .controls li.active').removeClass('active');
$('.navigation .controls li:first-child').addClass('active');

function slider() {

    $('.navigation .controls li.active').removeClass('active');
 $('.navigation .controls li:first-child').addClass('active');

    var programSliderWidth = $('.program-slider').width(),
        sliderContainer    = $('.program-slider .slides'),
        slides             = $('.program-slider .slides li'),
        move               = 0,
        position           = 0,
        totalSlides        = $('.program-slider .slides li').length;  


    //Apply width based on the width of the .program-slider
    slides.width(programSliderWidth);

    //Apply Maximum width based on number of slides
    sliderContainer.width(totalSlides * programSliderWidth);

    //Slider Controls
    $('.navigation .controls li').on('click', function() {
        position = $(this).index(); // -- CHANGE 1 --
        var move     = position*programSliderWidth;

        $('.program-slider .slides').css({'right': move});

        $('.navigation .controls li.active').removeClass('active');
        $(this).addClass('active');
    
    });

    //Slider Directional Controls
    $('.buttons .prev').on('click', function() {
        if( position > 0 ) { 
            position--;
            $('.program-slider .slides').css({'right': position * programSliderWidth }); // -- CHANGE 3 --
            $('.navigation .controls').find('li.active').removeClass('active').prev('li').addClass('active');

        }
    });

    $('.buttons .next').on('click', function() {
        if( position < totalSlides - 1 ) { 
             position++;
              $('.program-slider .slides').css({'right': position * programSliderWidth});   
              $('.navigation .controls').find('li.active').removeClass('active').next('li').addClass('active');

          }
    });
}


$(document).ready(function() {
    slider();
});

$(window).on('resize', function() {
    slider();
})
/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline; }

/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
  display: block; }

body {
  line-height: 1; }

ol, ul {
  list-style: none; }

blockquote, q {
  quotes: none; }

blockquote:before, blockquote:after,
q:before, q:after {
  content: '';
  content: none; }

table {
  border-collapse: collapse;
  border-spacing: 0; }

* {
  box-sizing: border-box; }

.program-slider {
  max-width: 1280px;
  margin: 0 auto;
  height: 200px;
  background-color: beige;
  overflow: hidden; }
  .program-slider .slides {
    overflow: hidden;
    position: relative;
    right: 0;
    -webkit-transition: all 0.3s linear; }
    .program-slider .slides li {
      position: relative;
      float: left;
      -webkit-transition: all 0.3s linear; }

.navigation {
  max-width: 1280px;
  margin: 0 auto; }
  .navigation .controls li {
    display: inline-block;
    padding: 10px;
    width: 25%;
    float: left; }
    .navigation .controls li.active {
      background-color: teal;
      color: #fff; }

.buttons {
  position: absolute;
  top: 30%; }

/*# sourceMappingURL=style.css.map */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="program-slider">
   <ul class="slides">
       <li>Slide 1</li>
       <li>Slide 2</li>
       <li>Slide 3</li>
       <li>Slide 4</li>
   </ul>


 <div class="buttons">
     <ul>
         <li class="prev">Prev</li>
         <li class="next">Next</li>
     </ul>
 </div>


</div>

<div class="navigation">
    <ul class="controls">
        <li>slide 1</li>
        <li>slide 2</li>
        <li>slide 3</li>
        <li>slide 4</li>
    </ul>
</div>
clestcruz
  • 1,111
  • 3
  • 25
  • 64
  • 2
    For me, I think your code should work fine.. but without `html` I can't tell about your selectors .. but if `:first-child` selector dosen't work you can try `$('.program-controls .program-list ul li:eq(0)').addClass('active');` – Mohamed-Yousef May 23 '17 at 02:28
  • Correction it seems to be working, the script to reset the class `active` to the first sibling works. But after clicking on the directional arrow controls it doesn't pass the class `active` to the next sibling – clestcruz May 23 '17 at 02:35
  • 1
    Ok till now we have your `.prev` button event not the `.next` one .. please provide all the related code .. or creart snippet/demo – Mohamed-Yousef May 23 '17 at 02:42
  • @Mohamed-Yousef added a demo to preview the problem – clestcruz May 23 '17 at 16:00
  • I've posted an answer .. please check it – Mohamed-Yousef May 23 '17 at 16:28

1 Answers1

1

Ok we will work with li index using css :eq selector instead of using .prev('li') and .next('li')

So your code can be like this find the explanation below

function slider() {

    $('.navigation .controls li.active').removeClass('active');
 $('.navigation .controls li:first-child').addClass('active');

    var programSliderWidth = $('.program-slider').width(),
        sliderContainer    = $('.program-slider .slides'),
        slides             = $('.program-slider .slides li'),
        move               = 0,
        position           = 0,
        totalSlides        = $('.program-slider .slides li').length;  


    //Apply width based on the width of the .program-slider
    slides.width(programSliderWidth);

    //Apply Maximum width based on number of slides
    sliderContainer.width(totalSlides * programSliderWidth);

    //Slider Controls
    $('.navigation .controls li').on('click', function() {
        position = $(this).index(); // -- CHANGE 1 --
        var move     = position*programSliderWidth;

        $('.program-slider .slides').css({'right': move});

        $('.navigation .controls li.active').removeClass('active');
        $(this).addClass('active');
    
    });

    //Slider Directional Controls
    $('.buttons .prev').on('click', function() {
      position = (position > 0) ? position - 1 : totalSlides - 1;
      $('.program-slider .slides').css({'right': position * programSliderWidth});
      $('.navigation .controls li').removeClass('active');
      $('.navigation .controls li:eq(' + position + ')').addClass('active');
    });

    $('.buttons .next').on('click', function() {
      position = (position < totalSlides - 1) ? position + 1 : 0;  
      $('.program-slider .slides').css({'right': position * programSliderWidth});
      $('.navigation .controls li').removeClass('active');
      $('.navigation .controls li:eq(' + position + ')').addClass('active');
    });
}


$(document).ready(function() {
    slider();
});

$(window).on('resize', function() {
    slider();
})
/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline; }

/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
  display: block; }

body {
  line-height: 1; }

ol, ul {
  list-style: none; }

blockquote, q {
  quotes: none; }

blockquote:before, blockquote:after,
q:before, q:after {
  content: '';
  content: none; }

table {
  border-collapse: collapse;
  border-spacing: 0; }

* {
  box-sizing: border-box; }

.program-slider {
  max-width: 1280px;
  margin: 0 auto;
  height: 200px;
  background-color: beige;
  overflow: hidden; }
  .program-slider .slides {
    overflow: hidden;
    position: relative;
    right: 0;
    -webkit-transition: all 0.3s linear; }
    .program-slider .slides li {
      position: relative;
      float: left;
      -webkit-transition: all 0.3s linear; }

.navigation {
  max-width: 1280px;
  margin: 0 auto; }
  .navigation .controls li {
    display: inline-block;
    padding: 10px;
    width: 25%;
    float: left; }
    .navigation .controls li.active {
      background-color: teal;
      color: #fff; }

.buttons {
  position: absolute;
  top: 30%; }

/*# sourceMappingURL=style.css.map */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="program-slider">
   <ul class="slides">
       <li>Slide 1</li>
       <li>Slide 2</li>
       <li>Slide 3</li>
       <li>Slide 4</li>
   </ul>


 <div class="buttons">
     <ul>
         <li class="prev">Prev</li>
         <li class="next">Next</li>
     </ul>
 </div>


</div>

<div class="navigation">
    <ul class="controls">
        <li>slide 1</li>
        <li>slide 2</li>
        <li>slide 3</li>
        <li>slide 4</li>
    </ul>
</div>

Explanation:

Your .prev and .next events depending on the value of position variable .. your problem was how to control this value in a good way in your code .. So I find it simple to control li by its index instead of next('li') and prev('li') and I control the position value by making a simple check with position = (position > 0) ? position - 1 : totalSlides - 1; on prev event and position = (position < totalSlides - 1) ? position + 1 : 0; on next event .. after that I use $('.navigation .controls li').removeClass('active'); to remove the class active from all li and use $('.navigation .controls li:eq(' + position + ')').addClass('active'); to determine the li index using css :eq() selector to add the class active to it

Hope the explanation help you to understand what is going on the code

Mohamed-Yousef
  • 22,772
  • 3
  • 17
  • 27
  • Thank you, sorry for my ignorance just for clarification what does this logic mean `position = (position > 0) ? position - 1 : totalSlides - 1` especially the `?` and `:` – clestcruz May 23 '17 at 23:47
  • @clestcruz you can read about it [here (?:)](https://en.wikipedia.org/wiki/%3F:#JavaScript) – Mohamed-Yousef May 24 '17 at 00:13
  • @clestcruz you can check this too https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Conditional_Operator and https://stackoverflow.com/a/6260001/3385827 hope it gives you a full view for how to use `?:` – Mohamed-Yousef May 24 '17 at 00:37
  • I see, it is a shortened if/else statement if I understand correctly – clestcruz May 24 '17 at 02:28