<script>
$(function() {
//Function to update counters on all elements with class counter
var doUpdate = function() {
$('#countdown').each(function() {
var count = parseInt($(this).html());
if (count !== 0) {
$(this).html(count - 1);
}
});
};
//Schedule the update to happen once every second
setInterval(doUpdate, 1000);
});
</script>
C'est un compte à rebour simple qui marche très bien, au chargement du div appelé avec ajax en jquery la première fois, le décompte se fait normalement à chaque seconde. Le problème survient quand je recharge le div une deuxième fois, et pire si plus, le décompte va 2, 3, 4 gois plus vite à chaque chargement de div. Donc si j'en déduit correctement, les setInterval() se superposent...
J'ai essayé ceci :
<script>
$(function() {
// Tentative de remise à zéro mais... :(
clearInterval(doUpdate);
$("#countdown").removeClass( ".active" );
//Function to update counters on all elements with class counter
var doUpdate = function() {
$('#countdown').each(function() {
var count = parseInt($(this).html());
if (count !== 0) {
$(this).html(count - 1);
}
});
};
//Schedule the update to happen once every second
setInterval(doUpdate, 1000);
});
</script>
Et plusieurs autres "solutions" sans succès...
Si je fais un refresh de la page, pas de souci, le compte à rebour redéfinle OK...
Que puis-je faire pour que le compte à rebour reparte de là où il devrait partir mais sans superpositions de setInterval() ?
Pour le coup, j'ai trouvé tout seul, et je poste ici si ça peut servir.
J'ai mis le script du compte à rebours dans l'index, ce script se charge donc au chargement et/ou refresh et une fois qu'on charge le script en ajax avec le span avec l'id qui correspond, ça marche. Pour ne pas avoir de superposition de setInterval(), et bien il suffit de ne charger qu'une fois au final...
Pour le coup, j'ai trouvé tout seul, et je poste ici si ça peut servir.
J'ai mis le script du compte à rebours dans l'index, ce script se charge donc au chargement et/ou refresh et une fois qu'on charge le script en ajax avec le span avec l'id qui correspond, ça marche. Pour ne pas avoir de superposition de setInterval(), et bien il suffit de ne charger qu'une fois au final...
Hello, il s'agit d'une solution en effet mais le mieux aurait été d'avoir une logique qui permet de bien clear l'interval comme il faut.
Première question : Est-ce que je tu utilise jQuery car tu utilise quelque chose qui demande d'importer ce dernier ou est-ce un choix personnel ? dans le second cas peux-tu nous détailler pourquoi tu l'utilise ?
Ensuite tu parle de charger dans l'index et que le script se charge en ajax mais on ne vois pas dans le code à quoi sa correspond exactement, il faudrait à minima donner le code qui fait ce chargement.
Enfin il y a plein de chose à redire dans le code :
Utilisation de "var" la ou un const ou let aurai suffit
tu fait une boucle sur tous les élements d'id "countdown" sauf que un id est unique dans un code html donc pourquoi boucler ?
tu te sers de la valeur qu'il y a dans ton countdown html pour faire le calcul. Pourquoi ne pas avoir simplement une variable ?
on va pas changer tous le code back pour ça mais il est préférable de renvoyer du json quand on fait de l'ajax plutôt que tous le html
Voici ce que cela donne :
Déjà dans le html j'ai mis le fichier "counter.js" dans la partie "head" du html avec l'attribut "defer" :
<script src="/counter.js" defer></script>
Ensuite au niveau du html j'ai fait quelque chose de simple :
const counterInputEl = document.getElementById('counterInput')
const submitCounterEl = document.getElementById('submitCounter')
const resultEl = document.getElementById('result')
let counterIntervalId = null
let counterEl = null
let counter = 0
function startCounter(newCounterValue) {
// Si l'élément n'existe pas, on arrête le compteur
if (counterEl === null) {
return undefined
}
// Si le compteur est déjà lancé, on l'arrête
if (counterIntervalId) {
clearInterval(counterIntervalId)
}
counter = newCounterValue
counterIntervalId = setInterval(() => {
counter = counter - 1
counterEl.innerHTML = counter
if (counter === 0) {
clearInterval(counterIntervalId)
}
}, 1000)
}
function fetchCounter(counterValue) {
return fetch(`/get_counter.php?counter=${counterValue}`)
.then((response) => response.text())
}
submitCounterEl.addEventListener('click', () => {
// On récupère la valeur du compteur
const counterValue = parseInt(counterInputEl.value)
// Si la valeur n'est pas un nombre, on arrête la fonction
if (isNaN(counterValue)) {
resultEl.innerText = 'Invalid counter value'
return undefined
}
fetchCounter(counterValue).then((html) => {
resultEl.innerHTML = html
// On récupère l'élément du compteur
counterEl = document.querySelector('.counter')
// On lance le compteur.
// J'ai utilisé ce qui est renvoyé par le serveur,
// mais on peut aussi utiliser la valeur du champ directement
startCounter(parseInt(counterEl.dataset.start))
})
})
Il y a des moyens d'optimiser le script largement mais c'est déjà un bon début.
My website : Mon serveur discord, Se demerder tout seul, Faille XSS et SQL