• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Blokowanie możliwości wielokrotnego uruchomienia tej samej funkcji

+1 głos
218 wizyt
pytanie zadane 11 lutego 2024 w JavaScript przez Piotrek2713 Mądrala (5,520 p.)

Mój timer w javascript jest już prawie gotowy

const timer = document.querySelector('.timer');
const hours = document.querySelector('#timer-hours');
const minutes = document.querySelector('#timer-minutes');
const seconds = document.querySelector('#timer-seconds');
const alarm = new Audio ('timer.mp3');

function formatNumbers(e)
{
    e.preventDefault();
    const span = e.target;
    if (e.code == 'Delete')
    {
        span.textContent == '00';
        return;
    }

    if (/^\d$/.test(e.key))
    {
        const currentValue = span.textContent, inputValue = e.key;

        let newValue = parseInt(currentValue + inputValue);
        if (newValue > 99) newValue = newValue.toString().slice(-2);
        if (newValue > 59) newValue = inputValue;
        span.textContent = ('00' + newValue).slice(-2);
    }
}

function countDown()
{
    if (hours.textContent == 0 && minutes.textContent == 0 && seconds.textContent == 0)
    {
        alarm.play();
    }
    else
    {
        setTimeout('countDown()', 1000);
        hours.setAttribute('contenteditable', 'false');
        minutes.setAttribute('contenteditable', 'false');
        seconds.setAttribute('contenteditable', 'false');
        if (seconds.textContent>0)
        {
            seconds.textContent--;
            if (seconds.textContent < 10)
            {
                seconds.textContent = '0' + seconds.textContent;
            }
        }
        else
        {
            seconds.textContent = 59;
            if (minutes.textContent>0)
            {
                minutes.textContent--;
                if (minutes.textContent < 10)
                {
                    minutes.textContent = '0' + minutes.textContent;
                }
            }
            else
            {
                minutes.textContent = 59;
                if (hours.textContent>0)
                {
                    hours.textContent--;
                    if (hours.textContent < 10)
                    {
                        hours.textContent = '0' + hours.textContent;
                    }
                }
            }
        }
    }
}
timer.addEventListener('keydown', formatNumbers);
window.addEventListener('keydown', (event) => {
    event.preventDefault();
    if (event.key === 'Enter')
    {
        countDown();
    }
})

Wszystko działa prawidłowo, prócz tego, że funkcję countDown można uruchomić nieograniczoną ilość razy, co obciąża procesor oraz przyspiesza timer. Jak naprawić ten błąd i uniemożliwić użytkownikowi wielokrotne wywołanie funkcji?

Codepen

komentarz 12 lutego 2024 przez VBService Ekspert (256,600 p.)
edycja 12 lutego 2024 przez VBService

Możesz też odliczanie zapisać za pomocą tzw. delty

[ pełny kod demonstracyjny on-line ]

const stopwatch = document.querySelector('.stopwatch'),
      spanValue  = stopwatch.querySelectorAll('[contenteditable]');
let intervalID, isCountingDown = false;

function formatNumbers(e) {
  e.preventDefault();
  const span = e.target;

  if (e.code == 'Delete')  { 
    span.textContent = '00';
    return;
  }

  if (/^\d$/.test(e.key)) {
    const currentValue = span.textContent, inputValue = e.key;

    let newValue = parseInt(currentValue + inputValue);
    if (newValue > 99) newValue = newValue.toString().slice(-2);
    if (newValue > 59) newValue = inputValue;
    span.textContent = ('00' + newValue).slice(-2);
  }
}

function countDown(countdownTime) {
  const currentTime = Date.now();
  const delta = countdownTime - currentTime;

  if (delta >= 0) {
    const hours = Math.floor(delta / (1000 * 60 * 60));
    const minutes = Math.floor((delta % (1000 * 60 * 60)) / (1000 * 60));
    const seconds = Math.floor((delta % (1000 * 60)) / 1000);

    spanValue[0].textContent = hours.toString().padStart(2, '0'); // ('00' + hours).slice(-2);
    spanValue[1].textContent = minutes.toString().padStart(2, '0'); // ('00' + minutes).slice(-2);
    spanValue[2].textContent = seconds.toString().padStart(2, '0'); // ('00' + seconds).slice(-2);
  } else {
    clearInterval(intervalID);
    isCountingDown = false;
    alert('Time is up!'); // alarm.play();
    setContenteditable(true);
  }
}

stopwatch.addEventListener('keydown', formatNumbers);
window.addEventListener('keydown', () => {
  if (event.key === 'Enter' && !isCountingDown) {
    isCountingDown = true;
    setContenteditable(false);

    const hours = parseInt(spanValue[0].textContent);
    const minutes = parseInt(spanValue[1].textContent);
    const seconds = parseInt(spanValue[2].textContent);
    const countdownTime = Date.now() + (hours * 60 * 60 * 1000) + (minutes * 60 * 1000) + (seconds * 1000);
    intervalID = setInterval(countDown, 1000, countdownTime);
  }
})

function setContenteditable(value) {
  for (const span of spanValue)
    span.setAttribute('contenteditable', value);
}

 

komentarz 12 lutego 2024 przez Piotrek2713 Mądrala (5,520 p.)
Ciekawe podejście do tematu. Spróbuję w przyszłości zastosować deltę

1 odpowiedź

+1 głos
odpowiedź 11 lutego 2024 przez SzkolnyAdmin Szeryf (89,690 p.)
wybrane 12 lutego 2024 przez Piotrek2713
 
Najlepsza
Blokowanie (dezaktywacja) elementu, ktorego np. klikniecie, powoduje wywołanie funkcji.

Wyrejestrowanie obsługi zdarzenia.

Zmienna statyczna, ktora przechowuje informację o uruchomieniu timera.
komentarz 12 lutego 2024 przez Piotrek2713 Mądrala (5,520 p.)
Dzięki, zmienna typu boolean pomogła

Podobne pytania

0 głosów
1 odpowiedź 469 wizyt
0 głosów
1 odpowiedź 416 wizyt
pytanie zadane 4 kwietnia 2019 w C i C++ przez Kaper99 Użytkownik (660 p.)
0 głosów
0 odpowiedzi 769 wizyt
pytanie zadane 9 maja 2018 w C# przez Ditrix Mądrala (5,650 p.)

93,425 zapytań

142,421 odpowiedzi

322,646 komentarzy

62,786 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
...