Fala Claudemir!
Na empresa aonde trabalho, passei por essa situação em muitos projetos. Para resolver, segui os passos abaixo. Talvez você possa fazer algo parecido.
1 - Crie um loader bacana que faça sentido para seu projeto aqui: https://loading.io/animation/icon/
PS: use o chrome para isso ;)
2 - Disponibilize seu arquivo de loader em uma pasta do seu projeto.
Ex: assets/commons/myEpicLoader.gif
3 - Crie uma classe ou utilize um data-attribute para identificar tudo o que precisa ser substuído pelo loader no momento da requisição.
Exemplo:
<button class="will-hide-on-request"></button>
4 - Defina o local aonde o loader deverá aparecer. Se serão requisições específicas, você precisará definir um data-attribute para cada um desses campos. Mas se for geral, uma classe serve bem.
Exemplos:
a - Requests globais
<div class="loader-will-be-here></div>
OU
<div data-loader="global"></div>
b - Resquest Específicos
<div data-loader="formCadastro">
5 - Você pode criar uma função para fazer o 'trabalho sujo' e chamar ela todas as vezes que precisar. Algo como:
function go_loader(place){
// O local que definimos no item 2
var loader = '<img class="loader-general" src="assets/commons/myEpicLoader.gif" />';
// Caso seja um request global, a função incluirá o loader em todos os locais que tiverem o atributo data-loader e esconderá o elemento. Lembre-se que pode ser uma classe também. Depende do que você definiu no item 4. Caso seja um local especifico, ele virá com a chamada da função. Você então apenas irá inserir o loader naquele local especifico.
$('.will-hide-on-request').addClass('hide');
$('*[data-loader="'+place+'"]').html(loader);
};
A função acima irá ser chamada antes de disparar o AJAX. Quando ele for finalizado (no sucesso, ou no erro) podemos chamar uma outra função para 'finalizar o loader.
function end_loader(place){
// O local que definimos no item 2
var loader = '<img class="loader-general" src="assets/commons/myEpicLoader.gif" />';
// Caso seja um request global, a função retirará o loader em todos os locais que tiverem o atributo data-loader e mostrará novmaento o elemento que escondemos previamente. Lembre-se que pode ser uma classe também. Depende do que você definiu no item 4. Caso seja um local especifico, ele virá com a chamada da função. Você então apenas irá retirar o loader naquele local especifico.
$('*[data-loader="'+place+'"]').html("");
$('.will-hide-on-request').removeClass('hide');
};
Feito!
Uma chamada global seria algo como:
function meuRequestAnimal(){
go_loader('global');
// SEU AJAX AQUI
// No sucesso ou erro do seu AJAX
end_loader('global');
};
Imagine que tenha um local em seu sistema que demora mais que os outros por exemplo. Você pode definir um data-attribute personalizado para ele:
<div data-loader="formCadastro">
E aí usar ele na hora de chamar seu AJAX:
function meuRequestAnimal(){
go_loader('formCadastro');
// SEU AJAX AQUI
// No sucesso ou erro do seu AJAX
end_loader('formCadastro');
};
Não se esqueça de definir os estilo CSS para seu loader. No exemplo usei a classe 'loader-general. Talvez te ajude, talvez não. Mas usei bastante esse exemplo e me salvava muito tempo. Além disso, eu conseguia aproveitar todas as funcionalidades de um projeto para o outro simplesmente substituindo o .gif do loader e alterando os estilos css daquela classe. Se vocẽ for por esse caminho, melhore a experiência no momento em que você esconde o elemento e mostrar o loader. Ao invés de simplesmente inserir uma classe que esconde o elemento com display:none, você pode transformar ele no loader ou retirar a visibilidade dele progressivamente antes de escondê-lo. Enfim, este foi só um exemplo simples.
Qualquer coisa, é só chamar!
Happy Coding! : )