Problema ao acessar o conteúdo de uma div quando esse conteúdo veio de uma chamada Ajax
-
09-06-2019 - |
Pergunta
Aqui está um exemplo de protótipo muito simples.
Tudo o que ele faz é, no carregamento da janela, uma chamada ajax que coloca um pouco de HTML em um div.
<html>
<head>
<script type="text/javascript" src="scriptaculous/lib/prototype.js"></script>
<script type="text/javascript">
Event.observe(window, 'load', function(){
new Ajax.Request('get-table.php', {
method: 'get',
onSuccess: function(response){
$('content').innerHTML = response.responseText;
//At this call, the div has HTML in it
click1();
},
onFailure: function(){
alert('Fail!');
}
});
//At this call, the div is empty
click1();
});
function click1(){if($('content').innerHTML){alert('Found content');}else{alert('Empty div');}}
</script>
</head>
<body><div id="content"></div></body>
</html>
O que é confuso é o contexto em que o Prototype entende que o div realmente contém coisas.
Se você observar a parte onSuccess da chamada ajax, verá que nesse ponto $('content').innerHTML contém coisas.
No entanto, quando verifico $('content').innerHTML logo após a chamada ajax, ele parece estar vazio.
Isso deve ser algum mal-entendido fundamental da minha parte.Alguém se importa em me explicar?
Editar
Eu só quero esclarecer uma coisa.Percebo que a chamada do Ajax é assíncrona.
Aqui está a ordem real em que as coisas estão sendo executadas e por que isso é confuso para mim:
- A página é carregada.
- A solicitação Ajax para get-table.php é feita.
- A chamada para click1() INSIDE onSuccess acontece.Vejo um alerta de que a div tem conteúdo.
- A chamada para click1() APÓS a chamada do Ajax acontece.Vejo um alerta de que a div está vazia.
Então é como se o código estivesse sendo executado na ordem em que foi escrito, mas o DOM não estivesse sendo atualizado na mesma ordem.
Editar 2Portanto, a resposta curta é que colocar o código onSuccess é o local correto.
Outro caso a considerar é aquele em que você faz uma chamada Ajax e depois faz outra chamada Ajax a partir do onSuccess da primeira chamada assim:
new Ajax.Request('foo.php',{
method: 'get',
onSuccess: function(response){
doAnotherAjaxCall();
}
});
function doAnotherAjaxCall(){
new Ajax.Request('foo.php',{
method: 'get',
onSuccess: function(response){
//Anything that needs to happen AFTER the call to doAnotherAjaxCall() above
//needs to happen here!
}
});
}
});
Solução
A primeira letra do AJAX significa “assíncrono”.Isso significa que a chamada AJAX é executada em segundo plano, ou seja,a chamada de solicitação AJAX retorna imediatamente.Isso significa que o código imediatamente após ser normalmente executado antes o manipulador onSuccess é chamado (e antes mesmo que a solicitação AJAX seja concluída).
Levando em consideração sua pergunta editada:em alguns navegadores (por ex.Firefox), as caixas de alerta não são tão modais quanto você imagina.O código assíncrono pode exibir uma caixa de alerta mesmo que outra já esteja aberta.Nesse caso, a caixa de alerta mais recente (aquela do código assíncrono) é exibida sobre a mais antiga.Isso cria a ilusão de que o código assíncrono foi executado primeiro.
Outras dicas
Sem ter tentado seu código:A chamada AJAX é executada de forma assíncrona.O que significa que seu Ajax.Request é acionado e, em seguida, passa para a chamada click1() que informa que o div está vazio.Em algum momento depois disso, a solicitação Ajax é concluída e o conteúdo é realmente colocado no div.Neste ponto a função onSuccess é executada e você obtém o conteúdo esperado.
É uma chamada Ajax, que é assíncrona.Isso significa que logo após a chamada da solicitação, a resposta ainda não voltou, é por isso que $('content') ainda está vazio.
O elemento onSuccess da chamada de função que você está fazendo para lidar com a chamada AJAX é executado no momento em que você recebe uma resposta de get-table.php.Esta é uma função Javascript separada que você diz ao navegador para chamar quando obtiver uma resposta de get-table.php.O código abaixo da sua chamada AJAX.Request é acessado assim que a chamada AJAX.Request é feita, mas não necessariamente antes de get-table.php ser chamado.Então, sim, acho que há um mal-entendido fundamental sobre como o AJAX funciona, provavelmente devido ao uso de uma biblioteca para ocultar os detalhes.