Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

vmdev

Iniciar script depois de um tempo pré-definido

Recommended Posts

Bom dia!

Eu tô com um probleminha aqui, espero que alguém consiga me ajudar.

Eu tenho dois elementos: h1 e h2, eu fiz um script para efeito de digitação pra ambos, só que eu quero que o efeito de digitação do h2 seja iniciado somente quando o h1 for terminado, ou, depois de um tempo que eu selecionar. Tentei fazer dessa forma, mas não deu certo:

<script>
                                function typeWrite (elemento) {
                                const textoArray = elemento.innerHTML.split('');
                                elemento.innerHTML = '';
                                textoArray.forEach((letra, i) => {
                                 setTimeout(function() {
                                     elemento.innerHTML += letra
                                 }, 75 * i)
                                
                                });
                    
                                }
                         const titulo = document.querySelector('h1')
                         typeWrite(titulo);
                         </script>

                         <script>

                            var segundos = 4;

                            setTimeout ( function typeWrite (elemento) {
                            const textoArray = elemento.innerHTML.split('');
                            elemento.innerHTML = '';
                            textoArray.forEach((letra, i) => {
                             setTimeout(function() {
                                 elemento.innerHTML += letra
                             }, 75 * i)
                            
                            });
                
                            }, segundos * 1000);

                     const titulo2 = document.querySelector('h2')
                     typeWrite(titulo2);
                     </script>

 

 

 Alguém pode ma falar qual é o erro? Obrigado!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá @vmdev,

 

Sua dúvida me intrigou e aceitei o desafio de fazer uma função que fizesse o que você quer fazer.

 

challenge-accepted-low.jpg.c9723fa865064112d814b6b3c4bf7d66.jpg

 

Tentei fazer isso quando comecei a programar e tive muitos problemas na epoca que acabei deixando o problema de lado e desisti do efeito. Pensei comigo, afinal de contas... tem essa biblioteca nova aqui... script.aculo.us que faz efeitos melhores, vou experimentar... (só quem é velho vai lembrar, rsss...)

 

O interessante nesse exercicio é quebrar os caracteres e fazê-los aparecer um a um em seu determinado tempo. Vi que no seu código você tentou isso utilizando o forEach aliado ao setTimeout. O problema dessa abordagem é que o forEach não vai esperar um timeout terminar para começar o outro... como pode ser visto no exemplo abaixo:

 

https://jsbin.com/vexozohaca/1/edit?js,console

 

Então comecei a pensar em programação funcional, onde a mesma função acaba se chamando várias vezes e aproveitando o poder de processamento de dados devido a sua imutabilidade.

 

Veja um exemplo bem simples do que estou falando...

 

function fatorial(numero) {
  if (numero <= 0) {
    return 1;
  }
  return numero * fatorial(numero - 1);
}

fatorial(5); // => 120

Perceba como o método fatorial chama ele mesmo e tem um breakpoint no começo para ele não se chamar infinitamente.

 

Mas chega de conceitos e vamos tentar aplicar isso ao seu problema...

 

function typewriter(texto, current) {
  if (!texto) {
    return;
  }

  alert((current || '') + texto[0]);
  
  typewriter(texto.substr(1), (current || '') + texto[0]);
}

Perceba como fazemos a função se chamar e para quando for o texto terminar. Agora, vamos incrementar isso com um timeout que será chamado.

 

function typewriter(texto, current) {
  if (!texto) {
    return;
  }

  alert((current || '') + texto[0]);
  
  setTimeout(function () {
    typewriter(texto.substr(1), (current || '') + texto[0]);
  }, 200);
}

E se a gente puder parametrizar esse tempo? Seria bacana, né?

 

function typewriter(texto, tempo, current) {
  if (!texto) {
    return;
  }

  alert((current || '') + texto[0]);
  
  setTimeout(function () {
    typewriter(texto.substr(1), tempo, (current || '') + texto[0]);
  }, tempo);
}

typewriter('meu texto', 1000);

Boa, tudo funciona conforme o combinado, ele chama o setTimeout no final de cada chamada, não encavalando chamadas setTimeout e podemos manipular a velocidade da mensagem... Perceba que o tempo foi adicionado em três lugares, na declaração da função, na chamada da mesma dentro do setTimeout e no final do setTimeout.

 

Agora, vamos focar naquele alert, que é onde se concentra a lógica do programa, seria interessante se a gente chamasse uma closure ou função anônima, assim como fizemos no setTimeout. Assim a gente pode definir um método para cada um de forma diferente...

 

function typewriter(texto, tempo, acao, current) {
  if (!texto) {
    return;
  }
  
  if (acao) {
    acao((current || '') + texto[0]);
  }

  setTimeout(function () {
    typewriter(texto.substr(1), tempo, acao, (current || '') + texto[0]);
  }, tempo);
}

typewriter('pipoca', 1000, function (texto) {
  alert("[" + texto.split('').join('][') + "]");
});

De novo, o argumento acao precisou ser adicionado em três lugares. Na declaração e na chamada do typewriter e na chamada, onde substituimos o alert. Aproveitei para adicionar uma verificação de se a acao existir... aqui dá pra implementar métodos de verificar se é uma função, se ele é chamável, etc... vamos nos atentar ao desafio...

 

Por último, precisamos fazer um callback que será executado quando a função terminar, assim podemos fazer o seu h2 executar somente quando terminar o outro...

 

function typewriter(texto, tempo, acao, callback, current) {
  if (!texto) {
    if (callback) { /* novo */
      callback(); /* novo */
    } /* novo */
    return;
  }
  
  if (acao) {
    acao((current || '') + texto[0]);
  }

  setTimeout(function () {
    typewriter(texto.substr(1), tempo, acao, callback /* novo */, (current || '') + texto[0]);
  }, tempo);
}

typewriter(
  'pipoca', // texto a ser utilizado
  1000, // tempo entre iteracoes
  function (texto) { // funcao que sera executada a cada iteracao
    alert("[" + texto.split('').join('][') + "]");
  },
  function () { // funcao que será chamada no final de tudo
    alert("fim da transmissão");
  }
);

Como está começando a ficar um pouquinho confuso, coloquei os comentários para ajudar a entender onde entra o callback e a chamada da typewriter no final... Bom, com isso já podemos utilizar nossa função a nosso favor...

 

https://jsbin.com/tamuzivulo/1/edit?html,js,output

 

<html>
<head>
	<meta charset="UTF-8">
	<title>Typewriter</title>
</head>
<body>
	<h1 id="h1">Teste simples</h1>

	<h2 id="h2">Sequencia de caracteres</h2>

	<script>
		function typewriter(texto, tempo, acao, callback, current) {
			if (!texto) {
				if (callback) {
					callback();
				}
				return;
			}

			if (acao) {
				acao((current || '') + texto[0]);
			}

			setTimeout(function () {
				typewriter(texto.substr(1), tempo, acao, callback /* novo */, (current || '') + texto[0]);
			}, tempo);
		}

		var h1 = document.getElementById('h1');
		var h2 = document.getElementById('h2');

		var h1Text = h1.innerText;
		h1.innerText = '';

		var h2Text = h2.innerText;
		h2.innerText = '';

		typewriter(
			h1Text,
			75,
			function (text) { h1.innerText = text },
			function () {
				typewriter(
					h2Text,
					100,
					function (text) { h2.innerText = '[' + text.split('').join('][') + ']'; }
				);
			}
		);
	</script>
</body>
</html>

Só desculpa pelo texto grande, mas acabei me empolgando. Espero que tenha ajudado nos seus estudos. Qualquer coisa, grita.

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por Rafael_Ferreira
      Não consigo carregar a imagem do captcha do meu formulário. Foi testado com o xampp e easyphp. Também não carregou a imagem de outros captcha. 
       
       
    • Por luiz monteiro
      Olá.
      Estou atualizando meu conhecimento com Front-End e me deparei com o seguinte problema.
      Criei um sistema para fazer o upload de imagens e alguns campos text.
      Algo bem simples para depois começar a estudar javascript para mostrar a miniatura....
      Mas quando saio do navegador Chrome ou da aba por mais de 3 minutos, ao retornar o navegador as vezes atualiza ou nem chega atualizar mas limpa os campos.
      Estou usando um Smart Motorola com Android, mas um amigo testou no iPhone e acontece a mesma coisa.
      Gostaria de saber se há como usar javascript para evitar isso?
      Agradeço desde já.

      <!DOCTYPE html>
      <html>
      <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <title>Uploader</title>
      </head>
      <body>
          <form action="?" method="post" enctype="multipart/form-data">
              <br><br>
              <div>selecione a imagem 1</div>
              <input type="file" name="foto1" accept="image/*">
              <br><br>
              <input type="text" name="nome_imagem1">
              
              <br><br>
              <input type="file" name="foto2" accept="image/*">
              <br><br>
              <input type="text" name="nome_imagem2">
              
              <br><br>

              <input type="file" name="foto3" accept="image/*">
              <br><br>
              <input type="text" name="nome_imagem3">
              
              <br><br>
              <input type="submit" value="Enviar">
              <br><br>
          </form>
      <?php
      if ($_SERVER['REQUEST_METHOD'] == 'POST')
      {
          vardump ($_FILES);
      }
      ?>
      </body>
      </html>
       
       
       
    • Por belann
      Olá!
       
      Estou usando o nextjs versão 15.2.3 e criei uma navbar que quando é carregado o programa aparece com a home, mas na hora de clicar na página produtos desaparece a navbar.
      A navbar esta sendo chamada no layout.tsx estou usando typescript
      e fica dessa forma
      <div>           <Navbar/>             <main>{children}</main>             </div>  
    • Por ILR master
      Fala pessoal, tudo bem?
       
      Eu tenho o seguinte código:
       
      <script>
         $(function(){
      var jElement = $('.fixar_banner');
      $(window).scroll(function(){
          if ( $(this).scrollTop() > 120 ){
              jElement.css({
                  'position':'fixed',
                  'top':'10px'
              });
          }else{
              jElement.css({
                  'position':'relative',
                  'top':'auto'
              });
          }
      });
      });
      </script>
       
      Porém, eu quero que a div fique fixa até que outro elemento apareça na tela, tipo o rodapé da página por exemplo. É mais ou menos como a página de notícia do uol.
      https://noticias.uol.com.br/internacional/ultimas-noticias/2025/01/19/sonho-americano-brasileiros-moram-em-carro-e-buscam-comida-no-lixo-nos-eua.htm
       
      Espero ter sido claro.
       
      Obrigado :)
       
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.