Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

175
Visualizações
Why I have to click on a button twice for the event to happen - javascript?

Context: Goal: Mimic the cancel sent email button in gmail. Current problem: I have to click the Cancel button twice for it to work.

Detail: The following code creates a Send button. After it was clicked, a countdown paragraph will display and started to count down from 10 to 0 and the button will change from Send to Cancel. The Cancel button is supposed to display a message (Sent email has been recalled!) immediately after the button was clicked. However, currently, I have to click the Cancel button twice for the recall message to show up. I wonder which line of code causes the problem?

Code below

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>DOM Demo</title>
    <link ref="icon" href="favicon.ico">
</head>

<body>
    <main>
        <div>
            <button id="action-button">Send</button>
            <p id="countdown-message"></p>
        </div>

    </main>
    <script>
        'use strict'

        const button = document.getElementById('action-button');
        button.addEventListener('click', changeButtonText)

        const countdownMessage = document.getElementById('countdown-message');
        let sec = 10;
        let timeoutId = 0;
        
        function changeButtonText() {
            if (button.innerText === 'Send') {
                button.innerText = 'Cancel';
                countDown();
            }
            else if (button.innerText === 'Cancel') {
                button.addEventListener('click',cancelSent);
            }
        }

        function countDown() {
            if (sec > 0) {
                showCountdownMessage();
                sec--;
                timeoutId = setTimeout(countDown, 1000);
            } else {
                showSentMessage();
            }
        }

        function cancelSent(){
            clearTimeout(timeoutId);
            countdownMessage.innerText = 'Sent email has been recalled!'
        }

        function showCountdownMessage() {
            countdownMessage.innerText = `The email will be sent in ${sec} seconds`;
        }

        function showSentMessage() {
            countdownMessage.innerText = 'Email has been sent!'
        }
    </script>
</body>

</html>

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

The problem is that you don't act on the user clicking Cancel straightaway. Instead you create a new event listener so the system won't do anything until the user clicks again and that event listener is invoked.

Remove the creation of a new event listener and instead call the cancelling function straightaway. Note, you also need to reset sec to its initial value otherwise the user gets a decreasing amount of time in which to decide to cancel the send.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>DOM Demo</title>
  <link ref="icon" href="favicon.ico">
</head>

<body>
  <main>
    <div>
      <button id="action-button">Send</button>
      <p id="countdown-message"></p>
    </div>

  </main>
  <script>
    'use strict'

    const button = document.getElementById('action-button');
    button.addEventListener('click', changeButtonText)

    const countdownMessage = document.getElementById('countdown-message');
    let sec = 10;
    let timeoutId = 0;

    function changeButtonText() {
      if (button.innerText === 'Send') {
        button.innerText = 'Cancel';
        countDown();
      } else if (button.innerText === 'Cancel') {
        // button.addEventListener('click',cancelSent);
        cancelSent();
        button.innerText = 'Send';
        sec = 10;
      }
    }

    function countDown() {
      if (sec > 0) {
        showCountdownMessage();
        sec--;
        timeoutId = setTimeout(countDown, 1000);
      } else {
        showSentMessage();
      }
    }

    function cancelSent() {
      clearTimeout(timeoutId);
      countdownMessage.innerText = 'Sent email has been recalled!'
    }

    function showCountdownMessage() {
      countdownMessage.innerText = `The email will be sent in ${sec} seconds`;
    }

    function showSentMessage() {
      countdownMessage.innerText = 'Email has been sent!'
    }
  </script>
</body>

</html>

about 4 years ago · Juan Pablo Isaza Relatório

0

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>DOM Demo</title>
</head>

<body>
    <main>
        <div>
            <button id="action-button">Send</button>
            <p id="countdown-message"></p>
        </div>

    </main>
    <script>
        'use strict'

        const button = document.getElementById('action-button');
        button.addEventListener('click', changeButtonText)

        const countdownMessage = document.getElementById('countdown-message');
        let sec = 10;
        let timeoutId = 0;
        
        function changeButtonText() {
            if (button.innerText === 'Send') {
                button.innerText = 'Cancel';
                countDown();
            }
            else if (button.innerText === 'Cancel') {
                cancelSent()
            }
            // efficient way to do the same 
            // switch(button.innerText){
            //     case 'Send':
            //         button.innerText = 'Cancel';
            //         countDown();
            //         break;
            //     case 'Cancel':
            //         cancelSent()
            // }
        }

        function countDown() {
            if (sec > 0) {
                showCountdownMessage();
                sec--;
                timeoutId = setTimeout(countDown, 1000);
            } else {
                showSentMessage();
            }
        }

        function cancelSent(){
            clearTimeout(timeoutId);
            countdownMessage.innerText = 'Sent email has been recalled!'
        }

        function showCountdownMessage() {
            countdownMessage.innerText = `The email will be sent in ${sec} seconds`;
        }

        function showSentMessage() {
            countdownMessage.innerText = 'Email has been sent!'
        }
    </script>
</body>

</html>
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda