Problème avec clearTimeout()

Résolu/Fermé
Cielmonbivouac - Modifié le 21 sept. 2022 à 16:27
 Cielmonbivouac - 21 sept. 2022 à 19:09

Bonjour à tous,

J'ai une petite question suite à un problème que je n'arrive pas à résoudre :

L'idée générale du projet est celle-ci : https://www.cielmonbivouac.com/index3.php

Je souhaite que les deux div des menus disparaissent quand l'on scrolle vers le bas, et apparaissent quand l'on scroll vers le haut. (ce qui marche parfaitement). Voici le code :

var container1 = document.getElementById("container1");
				var container2 = document.getElementById("container2");
				var container3 = document.getElementById("container3");

// [ ......... ]

// Quand on scroll la page : vers le haut, on affiche les container de menu, quand vers le bas, on les cache
var lastScrollTop = 0;

// element should be replaced with the actual target element on which you have applied scroll, use window in case of no target element.
window.addEventListener("scroll", function(){ // or window.addEventListener("scroll"....
var st = window.pageYOffset || document.documentElement.scrollTop; // Credits: "https://github.com/qeremy/so/blob/master/so.dom.js#L426"
if (st > lastScrollTop){
  // downscroll code
  container1.className = "container1_translate";
  container3.className = "container3_translate";

} else {
  // upscroll code
  container1.className = "container1_show";
  container3.className = "container3_show";

  container3_off_scroll = setTimeout(container3_translate, 10000);
  container1_off_scroll = setTimeout(container1_translate, 10000);


}
lastScrollTop = st <= 0 ? 0 : st; // For Mobile or negative scrolling
}, false); 

Ce qui marche nickel ! :) Cool !

Vous verrez également que j'ai défini un setTimeout permettant de masquer le div au bout de 10s : si les gens ne vont pas sur le menu, alors autant ne pas leur polluer la vie avec.

Le problème, c'est que quand l'on souhaite se balader sur les menus, le setTimeout fonctionne et le menu se ferme sous nos tristes yeux. Il faut donc annuler le SetTimeout si l'on se rend sur le menu.

// A chaque fois que le curseur ira sur le container1 ou 2 (hover en somme), on passe les deux containers en show, cad qu'on le garde visible
container1.addEventListener("mouseover", container1_show_mouse);
container3.addEventListener("mouseover", container3_show_mouse);

function container1_show_mouse()
{
	container1.className = "container1_show";

	clearTimeout(container1_off_scroll);
}

function container3_show_mouse()
{
	container3.className = "container3_show";

	clearTimeout(container3_off_scroll);
}

Seulement, que nenni, ca ne fonctionne pas.... Le menu se barre bien au bout des 10 secondes... Une idée d'où est le faute ?

Merci à tous par avance :)

Et une belle journée !
Windows / Firefox 104.0

5 réponses

jordane45 Messages postés 38145 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 25 avril 2024 4 650
21 sept. 2022 à 16:37

Bonjour,

sûrement un problème de portée de variable .

Il faudrait initialiser ta variable  container1_off_scroll  en dehors de toute fonction ou block if.. ( au tout début de ton js)

avec un 

  var container1_off_scroll = null;

Ensuite, celle-ci devrait bien être accessible dans tes fonctions.


0
Cielmonbivouac
21 sept. 2022 à 16:54

Salut Jordane et merci pour ta réponse !

J'ai essayé et ça ne marche malheureusement pas ... En faite, j'ai l'impression qu'à chaque scroll, un nombre incalculable de setTimeout se met en place (la boite menu se ferme bien plus que toute les 10 secondes, en particulier si je croll plusieurs fois vers le haut).

Y aurait-il moyen que le clearTimeout ne s'applique qu'une fois, contre un nombre énorme de setTimeout ? C'est un peu étrange comme question, mais vu que je ne suis pas familier avec les const, var, et autres objets à définir...

N'y aurait-il pas moyen que le nouveau setTimeout remplace l'ancien ? Car au pire, si ça se ferme qu'une fois, ça va. Mais là, ça plante et on ne peut quasiment pas ouvrir les menus...

J'espère être clair...

Merci encore à toi !

0
jordane45 Messages postés 38145 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 25 avril 2024 4 650
21 sept. 2022 à 17:06

Je n'ai pas regardé ton code en détail.

Mais en effet, il faudrait s'assurer que tu n'as pas déjà une instance de setTimeout lancée avant d'en recréer une.. sinon il t'en crééra autant de fois que tu fais appel à cette fonction...

En jouant avec une variable que tu mets à true lorsque tu as déjà activé un setTimeOut et à false lorsque tu le clear .. ça devrait le faire

0
Cielmonbivouac
21 sept. 2022 à 17:10

J'essaye de faire ça et je reviens vers toi :)

Merci beaucoup !

0
Cielmonbivouac
21 sept. 2022 à 17:27

Ca marche ! Merci beaucoup ! :)

Dois-je mettre le code, pour que ça serve à d'autre ?

0
jordane45 Messages postés 38145 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 25 avril 2024 4 650
21 sept. 2022 à 17:28

tu peux toujours.

On ne sait jamais. :-)

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Cielmonbivouac
21 sept. 2022 à 19:09

Voilà le code complet, pour ceux que ça intéresse :

CODE JS :

		// 2. Translation du menu des films

			// 2.1. On définit les variables et les fonctions d'apparitions ou disparitions des containers

				var container1 = document.getElementById("container1");
				var container2 = document.getElementById("container2");
				var container3 = document.getElementById("container3");

				var container3_off_scroll = null;
				var container1_off_scroll = null;
				var scroll_timer = false;

				function container1_translate()
				{
					container1.className = "container1_translate";

					clearTimeout(container1_off_scroll);
				}

				function container3_translate()
				{
					container3.className = "container3_translate";

					clearTimeout(container3_off_scroll);
				}

				function container1_show()
				{
					container1.className = "container1_show";
				}

				function container3_show()
				{
					container3.className = "container3_show";
				}

				

				function container1_show_mouse()
				{
					container1.className = "container1_show";

					clearTimeout(container1_off_scroll);
				}

				function container3_show_mouse()
				{
					container3.className = "container3_show";

					clearTimeout(container3_off_scroll);
				}

			// 2.2. Quand l'on est sur le container 1, il faut le garder ouvert

				// Instant inital : on ferme les container après 10 secondes
				if(container1.className == "container1_init")
				{
				container1_off_start = setTimeout(container1_translate, 15000);
				console.log("On a définit le timeout du container 1"); 
				} 
				
				if(container3.className == "container3_init")
				{
				container3_off_start = setTimeout(container3_translate, 15000);
				console.log("On a définit le timeout du container 3"); 
				} 

				// Quand on scroll la page : vers le haut, on affiche les container de menu, quand vers le bas, on les cache
				var lastScrollTop = 0;

					// element should be replaced with the actual target element on which you have applied scroll, use window in case of no target element.
					window.addEventListener("scroll", function(){ // or window.addEventListener("scroll"....
					   var st = window.pageYOffset || document.documentElement.scrollTop; // Credits: "https://github.com/qeremy/so/blob/master/so.dom.js#L426"
					   if (st > lastScrollTop){
					      // downscroll code
					      container1.className = "container1_translate";
					      container3.className = "container3_translate";

					      	if(scroll_timer)
				      		{
				      			clearTimeout(container3_off_scroll);
				      			clearTimeout(container1_off_scroll);
				      			scroll_timer = false;
				      		}

					   } else {
					      // upscroll code
					      container1.className = "container1_show";
					      container3.className = "container3_show";

					      if(scroll_timer == false)
					      {
					      container3_off_scroll = setTimeout(container3_translate, 5000);
					      console.log("On a définit le timeout scroll du container 1 à 5s"); 
					      container1_off_scroll = setTimeout(container1_translate, 5000);
					      console.log("On a définit le timeout scroll du container 3 à 5s"); 
					      scroll_timer = true; 
					  	  }

					   }
					   lastScrollTop = st <= 0 ? 0 : st; // For Mobile or negative scrolling
					}, false); 

				
				// A chaque fois que le curseur ira sur le container1 ou 2 (hover en somme), on passe les deux containers en show, cad qu'on le garde visible
				container1.addEventListener("mouseover", container1_show_mouse);
				container3.addEventListener("mouseover", container3_show_mouse);


				// Quand le curseur sort du container1, on peut le cacher après 1.5 secondes (fonction container1_translate ci dessus)
				container1.addEventListener("mouseout", container1_translate);
				container3.addEventListener("mouseout", container3_translate);

CODE CSS :

				.container1_show, .container1_init
				{
					transform: translateX(0);

					opacity: 1;

					transition-duration: 1s;
				}

				.container1_translate
				{
					transform: translateX(-45vh);

					opacity: 0.6;

					transition-duration: 0.8s;
				}

				.container3_show, .container3_init
				{
					transform: translateX(0);

					opacity: 1;

					transition-duration: 0.8s;
				}

				.container3_translate
				{
					transform: translateX(+27.77vh);

					opacity: 0.6;

					transition-duration: 0.8s;
				}

:)

En espérant que ça puisse servir à quelqu'un !!

Merci Jordane pour ton aide !

0