1

I just built a slideshow of images that has the following style:

  • Images that move after a few seconds.
  • Some circular buttons that when you click on them, go to the corresponding image.
  • Arrows on the left and right that when you click on them, go to the next image.

The slideshow works correctly. But the problem happens when after about 3 minutes surfing the internet, I return to the system tab, and the slider moves much faster than normal. The only way to return it to normal is to update the page.

I leave the code to see if there is an error:

HTML:

<!--=====================================
SLIDESHOW  
======================================-->

<div class="container-fluid" id="slide">

    <div class="row">

        <!--=====================================
        SLIDESHOW 
        ======================================-->

        <ul>

            <?php

                $servidor = Ruta::ctrRutaServidor();

                $slide = ControladorSlide::ctrMostrarSlide();

                foreach ($slide as $key => $value) {    

                    $estiloImgProducto = json_decode($value["estiloImgProducto"], true);
                    $estiloTextoSlide = json_decode($value["estiloTextoSlide"], true);
                    $titulo1 = json_decode($value["titulo1"], true);
                    $titulo2 = json_decode($value["titulo2"], true);
                    $titulo3 = json_decode($value["titulo3"], true);

                    echo '<li>

                            <img src="'.$servidor.$value["imgFondo"].'">

                            <div class="slideOpciones '.$value["tipoSlide"].'">';

                                if($value["imgProducto"] != ""){

                                echo '<img class="imgProducto" src="'.$servidor.$value["imgProducto"].'" style="top:'.$estiloImgProducto["top"].'%; right:'.$estiloImgProducto["right"].'%; width:'.$estiloImgProducto["width"].'%; left:'.$estiloImgProducto["left"].'%">';

                                }                   

                                echo '<div class="textosSlide" style="top:'.$estiloTextoSlide["top"].'%; left:'.$estiloTextoSlide["left"].'%; width:'.$estiloTextoSlide["width"].'%; right:'.$estiloTextoSlide["right"].'%">

                                    <h1 style="color:'.$titulo1["color"].'">'.$titulo1["texto"].'</h1>

                                    <h2 style="color:'.$titulo2["color"].'">'.$titulo2["texto"].'</h2>

                                    <h3 style="color:'.$titulo3["color"].'">'.$titulo3["texto"].'</h3>';

                                if($value["boton"] != ""){

                                    echo '<a href="'.$value["url"].'">

                                        <button class="btn btn-default backColor text-uppercase">

                                        '.$value["boton"].' <span class="fa fa-chevron-right"></span>

                                        </button>

                                    </a>';

                                }

                                echo '</div>    

                            </div>

                        </li>';

                }

            ?>      

        </ul>

        <!--=====================================
        PAGINATION
        ======================================-->

        <ol id="paginacion">

            <?php

                for($i = 1; $i <= count($slide); $i++){

                    echo '<li item="'.$i.'"><span class="fa fa-circle"></span></li>';

                }       

            ?>

        </ol>   

        <!--=====================================
        ARROWS
        ======================================-->   

        <div class="flechas" id="retroceder"><span class="fa fa-chevron-left"></span></div>
        <div class="flechas" id="avanzar"><span class="fa fa-chevron-right"></span></div>

    </div>

</div>

<center>

    <button id="btnSlide" class="backColor">

            <i class="fa fa-angle-up"></i>

    </button>

</center>

JS

/*=============================================
VARIABLES
=============================================*/

var item = 0;
var itemPaginacion = $("#paginacion li");
var interrumpirCiclo = false;
var imgProducto = $(".imgProducto");
var titulos1 = $("#slide h1");
var titulos2 = $("#slide h2");
var titulos3 = $("#slide h3");
var btnVerProducto = $("#slide button");
var detenerIntervalo = false;
var toogle = false;

$("#slide ul li").css({"width":100/$("#slide ul li").length + "%"})
$("#slide ul").css({"width":$("#slide ul li").length*100 + "%"})

/*=============================================   
INITIAL ANIMATION
=============================================*/

$(imgProducto[item]).animate({"top":-10 +"%", "opacity": 0},100)
$(imgProducto[item]).animate({"top":30 +"px", "opacity": 1},600)

$(titulos1[item]).animate({"top":-10 +"%", "opacity": 0},100)
$(titulos1[item]).animate({"top":30 +"px", "opacity": 1},600)

$(titulos2[item]).animate({"top":-10 +"%", "opacity": 0},100)
$(titulos2[item]).animate({"top":30 +"px", "opacity": 1},600)

$(titulos3[item]).animate({"top":-10 +"%", "opacity": 0},100)
$(titulos3[item]).animate({"top":30 +"px", "opacity": 1},600)

$(btnVerProducto[item]).animate({"top":-10 +"%", "opacity": 0},100)
$(btnVerProducto[item]).animate({"top":30 +"px", "opacity": 1},600)

setTimeout(function(){

    $(btnVerProducto[item]).mouseover(function(){

    $(this).css({"background":"#3CB484"});

    })

    $(btnVerProducto[item]).mouseout(function(){

    $(this).css({"background":"#35A679"});

    })

},100)



/*=============================================
PAGINATION
=============================================*/

$("#paginacion li").click(function(){

    item = $(this).attr("item")-1;

    movimientoSlide(item);

})

/*=============================================
MOVE FORWARD
=============================================*/

function avanzar(){

    if(item == $("#slide ul li").length -1){

        item = 0;

    }else{

        item++

    }

    interrumpirCiclo = true;

    movimientoSlide(item);

}

$("#slide #avanzar").click(function(){

    avanzar();

})

/*=============================================
BACK
=============================================*/

$("#slide #retroceder").click(function(){

    if(item == 0){

        item = $("#slide ul li").length -1;

    }else{

        item--

    }

    movimientoSlide(item);

})


/*=============================================
MOVEMENT SLIDE
=============================================*/

function movimientoSlide(item){

    // http://easings.net/es

    $("#slide ul").animate({"left": item * -100 + "%"}, 1000, "easeOutQuart")

    $("#paginacion li").css({"opacity":.5})

    $(itemPaginacion[item]).css({"opacity":1})

    interrumpirCiclo = true;

    $(imgProducto[item]).animate({"top":-10 +"%", "opacity": 0},100)
    $(imgProducto[item]).animate({"top":30 +"px", "opacity": 1},600)

    $(titulos1[item]).animate({"top":-10 +"%", "opacity": 0},100)
    $(titulos1[item]).animate({"top":30 +"px", "opacity": 1},600)

    $(titulos2[item]).animate({"top":-10 +"%", "opacity": 0},100)
    $(titulos2[item]).animate({"top":30 +"px", "opacity": 1},600)

    $(titulos3[item]).animate({"top":-10 +"%", "opacity": 0},100)
    $(titulos3[item]).animate({"top":30 +"px", "opacity": 1},600)

    $(btnVerProducto[item]).animate({"top":-10 +"%", "opacity": 0},100)
    $(btnVerProducto[item]).animate({"top":30 +"px", "opacity": 1},600)
}

/*=============================================
INTERVAL
=============================================*/

setInterval(function(){

    if(interrumpirCiclo){

        interrumpirCiclo = false;

    }else{

        if(!detenerIntervalo){

            avanzar();

        }

    }

},3000)

/*=============================================
APPEAR ARROWS
=============================================*/

$("#slide").mouseover(function(){

    $("#slide #retroceder").css({"opacity":1})
    $("#slide #avanzar").css({"opacity":1})

    detenerIntervalo = true;

})


$("#slide").mouseout(function(){

    $("#slide #retroceder").css({"opacity":0})
    $("#slide #avanzar").css({"opacity":0})

    detenerIntervalo = false;

})

1 Answers1

1

It may be that setInterval events in the event queue do not get processed after a page has been left inactivate (not on the foreground) for a while. Then when you get back to it, all the pending events are processed giving a "racing" effect.

You can prevent this by using a chain of setTimeout instead of one setInterval. The next setTimeout will only be called if the current cycle-code has effectively executed:

function nextCycle(){
    if(interrumpirCiclo){
        interrumpirCiclo = false;
    }else{
        if(!detenerIntervalo){
            avanzar();
        }
    }
    setTimeout(nextCycle, 3000);
}
setTimeout(nextCycle, 3000);
trincot
  • 317,000
  • 35
  • 244
  • 286
  • 1
    I use this pattern from time to time as well, but it may be easier to keep the code correct by introducing a debounce instead. – Jason Jan 17 '19 at 22:00
  • The debounce method is preferred. Also, if introducing `setTimeout` it may be helpful to also include `clearTimeout` since there are other controlling elements – Cue Jan 17 '19 at 22:01
  • Indeed, instead of the `interrumpirCiclo` variable check, `clearTimeout` would be the more logical choice. There are several other things that could be improved, including in the PHP code. But I just focussed on the essence of the question. – trincot Jan 17 '19 at 22:10
  • Suggest some change to what @trincot has contributed? –  Jan 17 '19 at 22:12
  • @Cue How would it be with the debounce method? –  Jan 17 '19 at 22:14
  • @Jason I also ask you, since it does not allow me to tag two people in a comment –  Jan 17 '19 at 22:15
  • Debounce is typically done two ways. Either you schedule a function to run in n milliseconds with cancelTimeout/setTimeout, or you run the function immediately, set a flag indicating "don't run again" and then clear the flag with a setTimeout. Any calls that come in while the flag is set terminate immediately. The latter is smoother for interactions, the former is friendlier for background activities (and tends to be better for initial page load time) – Jason Jan 17 '19 at 23:20
  • @Jason Thanks for the explanation, I am reading an article about this. If it's not too much trouble, could I post an example like the user Trincot did? –  Jan 17 '19 at 23:33
  • @Jason I have not managed to understand well how the method you mention would work in my code. Could you give me an example taking into account my code, to achieve what you say? –  Jan 18 '19 at 00:24
  • @JohnJ., now that your code works I would advise to either try it with a debounce implementation, and if you bump into a problem, ask a specific, new question about that. Or, alternatively, you could post your working code on [CodeReview](https://codereview.stackexchange.com/) and ask how it could be improved. But be sure to add more comments to your code so it is clear what each variable is needed for. Also read what [you need to do](https://codereview.meta.stackexchange.com/a/2438/109294) for a good question there. – trincot Jan 18 '19 at 09:21