Jump to content
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!

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • By Leonardo Ortega
      Prezados, bom dia.
      sou novo por aqui, e me deparei com esta situação:
      estou desenvolvendo um projeto e tudo começou quando apenas mudei o banco de dados que estava conectado. Ou seja, se eu me conecto ao baco de dados anterior, volta todo código html, porém, se conecto ao banco de dados atual as divs desaparecem. 
       
      obs: Isso tb acontece quando eu desativo o php tudo volta como a imagem 1 e se eu ativo fica como a imagem2.
       
      quem pode me ajudar.. desde já muito obrigado.  


    • By Richard.Ribeiro
      Fala Pessoal.. Bom dia.. uma ajuda por favor.
      não sei se e a melhor opção mais, gostaria de criar um id sequencial id="material"
      para resolver seguinte problema.. com javascript eu crio select com dados selecionados anteriormente, e crio mais opção no caso de haver mais pedido, porém toda vez que preciso troca a categoria o PRIMEIRO selecte que já possui um item e resetado. como posso resolver isso O PRIMIEIRO SELECT NÃO MUDAR. uma vez que á possui value selected
       
      segue todo código:

        <div id="box" >
        <form id="cadastro"  method="post">
          <?php
            if(isset($_POST['acao'])){
              $ide = $_POST['ide'];
              $data = $_POST['data_pedido'];
              $username=$_SESSION['username'];
              $justificativa = $_POST['justificativa'];
              $id_tipo_material = $_POST['material'];
              $qnt_solicitada = $_POST['qnt_solicitada'];

              //cadastrar no banco de dados!
                  $gravar = new Painel();
                  $id_gsm = $gravar->cadastrarGsm($data,$username,$justificativa,$ide);
                  $gravar->cadastrarItem($id_gsm,$id_tipo_material,$qnt_solicitada);
                  Painel::alert('sucesso','Pedido realizado com sucesso!');
                  }
                  $ConsultaIde = ConexaoBD::conectar()->prepare("SELECT  vsat_gilat, 'IDE: '||vsat_gilat|| ', Situação:'|| situacao|| ', Localidade:'||localidade|| ', Logradouro: '||logradouro as local
        FROM vsat WHERE vsat_gilat != '' AND situacao = 'Ativo'");
                  $ConsultaIde->execute();
                  $ConsultaIde = $ConsultaIde->fetchAll();
        ?>
        <div >
        <div class="form-group">
              <label>Selecione uma IDE</label>
              <select class="ide" name="ide" id="ide" required>
                <option disabled selected>-- Selecione IDE --  </option>
                  <?php
                  foreach ($ConsultaIde as $key => $value) {
                    ?>
                    <option value="<?php echo $value['vsat_gilat'];?>">
                      <?php echo $value['local'];?>

                </option>
              <?php }?>
              </select>

              <label>Data da Solicitação do Material :</label>
              <input type="text"value="<?php   echo date('d/m/Y');    ?>"  name="data_pedido" readonly >
        </div><!--form-group-->
            <div class="form-group">
              <label>Justificativa do pedido:</label>
              <textarea  rows="8" cols="80" name="justificativa" required></textarea>
        </div><!--form-group-->

        <div class="form-group">
              <label>Selecione Sistema:</label>
              <select name="id_categoria" id="id_categoria">
              <option selected disabled> --- Selecione o Sistema ---</option>
            <?php
        $consulta= ConexaoBD::conectar()->prepare("SELECT id_sistema, descricaos FROM public.cadastrar_sistema");
        $consulta->execute();
        while($row_cat_post = $consulta->fetch(PDO::FETCH_ASSOC) ) {
        echo '<option value="'.$row_cat_post['id_sistema'].'">'.$row_cat_post['descricaos'].'</option>';
              }
        ?>
          </select>
        </div><!--form-group-->
        <div class="form-group">
          <label>Selecione Padrão:</label>
          <span class="carregando">Aguarde, carregando...</span>
          <select name="id_sub_categoria" id="id_sub_categoria" >
            <option value="">--- Selecione o Padrão ---</option>
          </select>
        </div><!--form-group-select-->

        </div>
        <div class="pedido">
          <div class="remover">
          <label>Selecione Material:</label>
          <span class="carregando">Aguarde, carregando...</span>
          <select name="material[]" id="material">
            <option value="">--- Selecionte o Material ---</option>
          </select>
          <input type="text" id="quantidade" name="qnt_solicitada[]" placeholder="Digite a Quantidade" >
      <button type="button" name="button" class="removedor">Remover Item</button>
      </div>
      </div>
      </div>
        <button type="button" name="button" class="clonador">Novo Item</button>
        <input type="submit" name="acao" value="Cadastrar!">
        </form>
       
       
       
       
       
       
       
        <script type="text/javascript" src="https://www.google.com/jsapi"></script>
                <script type="text/javascript">
                  google.load("jquery", "1.4.2");
                </script>
      <script  src="<?php echo INCLUDE_PATH_PAINEL ?>js/jquery-3.4.1.min.js"></script>
      <script type="text/javascript">
        $(function(){
          $('#id_categoria').change(function(){
            if( $(this).val() ) {
              $('#id_sub_categoria').hide();
              $('.carregando').show();
              $.get('sub_categorias_post?search=',{id_categoria: $(this).val(), ajax: 'true'}, function(j){
                html = $.parseHTML(j);
                j=JSON.parse(html[16].textContent.trim());
                var options = '<option value="">Escolha Subcategoria</option>';
                for (var i = 0; i < j.length; i++) {
                  options += '<option value="' + j.id + '">' + j.nome_sub_categoria + '</option>';
                }
                $('#id_sub_categoria').html(options).show();
                $('.carregando').hide();
              });
            } else {
              $('#id_sub_categoria').html('<option value="">– Escolha Subcategoria –</option>');
            }
          });
        });
        $(function(){
          $('#id_sub_categoria').change(function(){
            if( $(this).val() ) {
              $('#material').hide();
              $('.carregando').show();
              $.get('sub_categorias_post2?search=',{id_sub_categoria: $(this).val(), ajax: 'true'}, function(j){
                html = $.parseHTML(j);
                console.log(html);
                j=JSON.parse(html[16].textContent.trim());
                var options = '<option value="">Escolha Subcategoria</option>';
                for (var i = 0; i < j.length; i++) {
                  options += '<option value="' + j.id + '">' + j.nome_sub_categoria + '</option>';
                }
                $('#material').html(options).show();
                $('.carregando').hide();
              });
            } else {
              $('#id_sub_categoria2').html('<option value="">– Escolha Subcategoria –</option>');
            }
          });
        });
        </script>
        <script>
        $(document).ready(function(){
       
              $(document).on('click', '.clonador', function(e){
                var elm_html = $('.pedido').html();
                var counter = 0;  //faz uma cópia dos elementos a serem clonados.
                  e.preventDefault();
                  var elementos = elm_html.replace(/\[[0\]]\]/g, '['+ counter +']');  //substitui o valor dos index e incrementa++
                  counter++;
                  $('#cadastro').append(elementos);  //exibe o clone.
              });
          });

          $(document).on('click', '.removedor', function (event) {
            event.preventDefault();
            $(this).parents('.remover').remove(); // navega até o pai com a classe pedido e remove ele inteiro
          });
        </script>
       
        <?php
        die();
        ?>
      </div><!--box-content-->
    • By Renan Leite
      Fala pessoal, Estou utilizando grunt + babel para compilar meu código, acontece que minhas pastas estão organizadas da seguinte maneira.
      - pasta1 - amd -src - arquivo.js - pasta2 - amd -src - arquivo.js - pasta3 -subpasta3 - amd - src -arquivo.js E eu só consigo usar o babel de uma forma muito específico, por exemplo:
      grunt.initConfig({ babel: { options: { sourceMap: false, presets: ['env'] }, dist: { files: [{ expand: true, cwd: './pasta1/amd/src', // aqui so especifico a pasta1 src: ['*.js'], dest: '.pasta1/amd/babel/' // aqui so especifico a pasta1 }] } } Eu queria que ele rodasse em todas as pastas amd/src e gerasse dentro da propria pasta src/ os arquivos compilados pelo babel, já tentei o seguinte:
      grunt.initConfig({ babel: { options: { sourceMap: false, presets: ['env'] }, dist: { files: [{ expand: true, cwd: '**/amd/src', src: ['*.js'], dest: '**/amd/babel/' }] } } CWD: Não sei porque nao funciona, a ideia era pegar todas as pastas que contem as pastas amd/src e tornar isso a base
      DEST: nessa parte eu não faço ideia de como deixar o dest (pasta babel/ gerada) exatamente dentro da pasta que está o src, por exemplo... dentro de pasta1/src criar a pasta babel/ com todos arquivos .js compilados da pasta1, dentro de pasta2/src criar a pasta babel/ com todos arquivos .js compilados da pasta2
    • By thgsousa312
      uma função que recebe uma frase e uma palavra antiga e uma palavra nova. A função deve retornar uma string contendo a frase original, mas com a última ocorrência da palavra antiga substituída pela palavra nova. A entrada e saída de dados deve ser feita no programa principal. Exemplo:  
      Frase: “Quem parte e reparte fica com a maior parte”
      Palavra antiga: “parte”  Palavra nova: “parcela”
      Resultado a ser impresso no programa principal: “Quem parte e reparte fica com a maior parcela”
       
      function trocarNome(){
              
          var frase = document.getElementById("frase").value;
          var strAntiga = document.getElementById("strAntiga").value;
          var strNova = document.getElementById("strNova").value;
          //frase = frase.split(" ");
          var a = frase.lastIndexOf(strAntiga);
          var fras2 = frase.lastIndexOf(strAntiga).replace(strAntiga,strNova);
          document.getElementById("demo").innerHTML = "Certo";
      }
×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.