Ir para conteúdo
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

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora

  • Conteúdo Similar

    • Por Giovanird
      Olá a todos!
      Tenho uma pagina que possui uma DIV onde coloquei uma pagina PHP.
      Uso a função setInterval para atualizar a pagina inclusa dentro da DIV.
      O problema é que ao acessar o site , a DIV só me mostra a pagina inclusa somente quando completo o primeiro minuto.
      Preciso que a pagina inclusa já inicie carregada
       
      Meu código JavaScript e a DIV com a pagina PHP
       
      <script> function atualiza(){ var url = 'direita.php'; $.get(url, function(dataReturn) { $('#direita').html(dataReturn); }); } setInterval("atualiza()",60000); </script> <div> <span id="direita"></span> </div>  
    • Por Thiago Duarte
      Oi, gostaria de arrastar imagem e ao soltar formar bloco html, meu bloco de html ficaria com nome, content-1.html, content-2.html, etc
       
      Alguem pode me ajudar?
    • Por juliosonic
      Boa noite..
      Estou desenvolvendo um site de https://www.maithunatantra.com.br/ e estou com um duvida sobre o menu de navegação da versão mobile.
      O menu que tem o dropdown "Terapeutas" e "Terapias" quando clico em cima ele expande como deve ser, mas quando clico denovo para recolher os submenus
      nao acontece nada.. segue o trecho do codigo do menu..
      <div class="collapse navbar-collapse" id="navbarsExample09">             <ul class="navbar-nav ml-auto">               <li class="nav-item  active"><a class="nav-link" href="index.html">Home</a></li>               <li class="nav-item  active"><a class="nav-link" href="about-us.html">Quem Somos</a></li>               <li class="nav-item dropdown1">                     <a class="nav-link dropdown-toggle" data-toggle="dropdown1" href="#">Terapeutas</a>                     <ul class="dropdown-menu">                         <li><a class="dropdown-item" href="terapeuta-julio-cezar.html">Julio Cezar</a></li>                         <li><a class="dropdown-item" href="terapeuta-pamela-priscila.html">Pamela Priscila</a></li>                     </ul>                                    </li>               <li class="nav-item dropdown">                     <a class="nav-link dropdown-toggle" data-toggle="dropdown1" href="#">Terapias</a>                     <ul class="dropdown-menu" aria-labelledby="dropdown01">                         <li><a class="dropdown-item" href="o-que-e-reiki.html">O que é Reiki</a></li>                         <li><a class="dropdown-item" href="beneficios-reiki.html">Benefícios do Reiki</a></li>                         <li><a class="dropdown-item" href="principios-reiki.html">Princípios do Reiki</a></li>                         <li><a class="dropdown-item" href="animais-reiki.html">Reiki em Animais</a></li>                         <li><a class="dropdown-item" href="animais-reiki.html">Estudos Sobre Reiki</a></li>                         <li><a class="dropdown-item" href="terapia-massagem-tantrica.html">Terapia Tântrica</a></li>                     </ul>               </li>               <li class="nav-item  active"><a class="nav-link" href="blog.html">Blog</a></li>                <li class="nav-item"><a class="nav-link" href="contato.html">Contato</a></li>             </ul>         </div>  
      Massagem Tantrica em Curitiba
      Tantra Curitiba
      Massagem Tântrica
      Tantra
      Julio Darshan

      Obrigado
      Att
      Julio Cezar
       
       
       
×

Informação importante

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