toggle divs by time or by click

I am working with the following js:

$(document).ready(function () {
  var allBoxes = $("div.boxes").children("div");
  transitionBox(null, allBoxes.first());
});

function transitionBox(from, to) {
  function next() {
      var nextTo;
      if (to.is(":last-child")) {
          nextTo = to.closest(".boxes").children("div").first();
      } else {
          nextTo = to.next();
      }
    to.fadeIn(500, function () {
        setTimeout(function () {
            transitionBox(to, nextTo);
        }, 5000);
    });
  }

   if (from) {
      from.fadeOut(500, next);
  } else {
      next();
  }
}

In which I have several divs going through time. But now I would like it to happen with the click too. I tried to get them to pass with the IDs in the divs but it didn't work for me. I understand it's something with an onclick event but I don't know very well how to do it.

Any ideas ? Thank you very much. ( here you have the jsfiddle in case it helps )

  $(document).ready(function () {
      var allBoxes = $("div.boxes").children("div");
      transitionBox(null, allBoxes.first());
  });

  function transitionBox(from, to) {
      function next() {
          var nextTo;
          if (to.is(":last-child")) {
              nextTo = to.closest(".boxes").children("div").first();
          } else {
              nextTo = to.next();
          }
          to.fadeIn(500, function () {
              setTimeout(function () {
                  transitionBox(to, nextTo);
              }, 5000);
          });
      }
      
      if (from) {
          from.fadeOut(500, next);
      } else {
          next();
      }
  }
.boxes div{
  display:none;
}
.sizeR{
  width:500px;
  height:500px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="boxes">
    <div class="box1" id="1">
      text1
      <a href="#2" ><img class="sizeR" src="http://rlv.zcache.es/van_los_platanos_pegatina_cuadrada-r144680d35e3e45a0ad2282b310141c3d_v9wf3_8byvr_324.jpg"></a>  
    </div>
    <div class="box2" id="2">
      text2
      <a href="#3" ><img class="sizeR" src="http://rlv.zcache.es/pares_de_platanos_del_dibujo_animado_pegatina_cuadrada-r46c488b848514841a3aa27aaec211f22_v9wf3_8byvr_324.jpg"></a>  
    </div>
    <div class="box3" id="3">
      text3
      <a href="#1" ><img class="sizeR" src="http://rlv.zcache.es/deme_los_platanos_pegatina_cuadrada-r25a2e828474b4281b475f1148b382be4_v9wf3_8byvr_324.jpg"></a>
    </div>
</div>
 2
Author: toledano, 2016-09-09

1 answers

You could add a click event to the boxes container and use the selector :visible to know which one is currently showing.

I had to make some modifications to your code like extracting the findNext function to know what the next element is and not having to repeat the selection algorithm you had created. The timeout is also necessary to clean it in each transition otherwise you change the image ahead of time.

Of this form you only have to use one event click instead of several individual events which will allow you to add any number of elements without changing any code.

$(document).ready(function() {
  var boxContainer = $('.boxes');
  var allBoxes = boxContainer.children("div");
  var timeout;
  transitionBox(null, allBoxes.first());

  boxContainer.click(function() {
    var from = boxContainer.children('div:visible');
    var to = findNext(from);
    transitionBox(from, to);
  });

  function findNext(to) {
    if (to.is(":last-child")) {
      return to.closest(".boxes").children("div").first();
    } else {
      return to.next();
    }
  }

  function transitionBox(from, to) {
    clearTimeout(timeout);

    function next() {

      var nextTo = findNext(to);

      to.fadeIn(500, function() {
        timeout = setTimeout(function() {
          transitionBox(to, nextTo);
        }, 5000);
      });
    }

    if (from) {
      from.fadeOut(500, next);
    } else {
      next();
    }
  }
});
.boxes div {
  display: none;
}
.sizeR {
  width: 500px;
  height: 500px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="boxes">
  <div class="box1" id="1">
    text1
    <a href="#2">
      <img class="sizeR" src="http://rlv.zcache.es/van_los_platanos_pegatina_cuadrada-r144680d35e3e45a0ad2282b310141c3d_v9wf3_8byvr_324.jpg">
    </a>
  </div>
  <div class="box2" id="2">
    text2
    <a href="#3">
      <img class="sizeR" src="http://rlv.zcache.es/pares_de_platanos_del_dibujo_animado_pegatina_cuadrada-r46c488b848514841a3aa27aaec211f22_v9wf3_8byvr_324.jpg">
    </a>
  </div>
  <div class="box3" id="3">
    text3
    <a href="#1">
      <img class="sizeR" src="http://rlv.zcache.es/deme_los_platanos_pegatina_cuadrada-r25a2e828474b4281b475f1148b382be4_v9wf3_8byvr_324.jpg">
    </a>
  </div>
</div>

You could also add a throttle to your function click to display correctly if you are given many clicks in a row this way.

// 500ms es el tiempo que se toma tu imagen en aparecer
boxContainer.click($.throttle(500, function() {
    var from = boxContainer.children('div:visible');
    // .......
    // Codigo del click
}));
 3
Author: devconcept, 2016-09-09 14:20:30