11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous!

Voilà, j'ai un petit problème.. je fait un site web qui fait des changements de page en ajax pour que ce soit tout sweet pour les yeux..! Donc j'ai fait appel à la fonction .load de JQuerry.. tout fonctionne mais il y a un petit truc qui m'énerve..!

En gros, quand l'utilisateur change la page, la page afficher actuellement fait un fadeOut... jusque là c'est bien

J'appelle la fonction qui affiche le nouveau contenu après l’exécution de timer qui est de la même durée que le fadeOut, histoire que le nouveau contenu ne se charge pas durant le fade out...!

Jusque l'à tout marche bien! Sauf que quand la nouvelle page fait un fadeIn, c'est le contenu de l'ancienne page qui affiche puis PAF elle change au nouveau en un seul coup... bref c'est laid.

en faite ce problème arrive seulement avec des page un peu plus lourde disons...! On dirait qu'il a de la difficulté à loader le tout..! Pourtant quand j'utilise le .load() je fais bien load(url,afficherNouveauContenu()) , et le deuxième argument est supposément actionner la fonction afficherNouveauContenu lorsque le tout a finit de loader non?

Enfin, bref, voici mon code..!

function changerPage(url){
$("#conteneur").fadeOut(500);
setTimeout(function(){$('#conteneur').load(url,afficherNouveauContenu()); return false;},500);
}

function afficherNouveauContenu(){
$("#conteneur").fadeIn(800); //ensuite on fait apparaitre nouveau contenu
}
By the way.. ça load hyper bien sur mon serveur local, mais sur mon serveur web c'est là que ça fait des problèmes!
Salut !


Tu fais surement de l'ajax pour afficher ton contenu et je pense que le problème vient de là.
En effet quand tu fais de l'ajax tu peux choisir asynchrone ou synchrone, pour éviter d'avoir ce chevauchement de l'ancienne page mets ta requête ajax en synchrone.


Donne moi des nouvelles !
Tu utilises jQuery ? Tu lis la doc de jQuery.Ajax()

EDIT : En fait ton erreur vient surtout de l'utilisation de setTimeout au lieu de la callback de fadeOut
Modifié par jo_link_noir (18 Sep 2012 - 23:08)
Heu ATTENTION,

Faire en sorte que sa requête AJAX soit synchrone n'est jamais une bonne solution. Justement, ajax sert à éviter des chargements synchrone, forcer le comportement inverse est dans presque tous les cas totalement aberrant.

Ce forum est sensé promouvoir les bonnes pratiques de développement. Vouloir aider c'est très bien, mais quand on donne de mauvais conseils sans explication et sans justification, on fait le contraire.

----------

Le bug est que tu passe une fonction `afficherNouveauContenu()` avec ses parenthèse en guise de callback. Ce faisant, tu appelle cette fonction immédiatement, sans attendre l'exécution du callback. Ce que tu dois passer, c'est la référence à une fonction. Tu devrais donc l'écrire ainsi:


$('#conteneur').load(url, afficherNouveauContenu);


Ensuite, le problème plus profond, c'est que tu ne gère pas efficacement l'ordre de plusieurs actions synchrone qui se produisent en même temps (ton animation et ta requête ajax). (L'utilisation de setTimeout peut sembler satisfaisante, mais la fonction n'est pas fiable et entrainera parfois un délais, parfois une avance)

Il existe plusieurs solutions de mettre de l'ordre dans nos actions asynchrones, mais la meilleure est l'utilisation des `Promises` (jQuery en propose d'ailleurs une implémentation : http://api.jquery.com/category/deferred-object/ )

Ainsi, une solution beaucoup plus propre pourrait ressembler à ceci:


function changerPage( url ) {
	var $conteneur = $("#conteneur");
	
	$.when(
		$conteneur.fadeOut(500),
		$conteneur.load(url)
	)
	.then(function() {
		$conteneur.fadeIn(800);
	});
}


(bien que ton code fonctionnera si tu retire seulement les parenthèses comme expliqué plus haut)
Modifié par Vaxilart (19 Sep 2012 - 05:08)
Merci Vaxilart! Ta réponse est très TRÈS bien expliqué! (Et en plus elle marche Smiley biggrin )

En faite la première fonctionne super bien mais la deuxième que tu me propose m'a l'air beaucoup plus ''clean'', sauf que pour une raison X.. firebug me dit qu'il ne reconnait pas la fonction $.when ..?

Avez-vous une idée?
Salut JeanGab,

La fonction jQuery.when a été ajouté à la version 1.5 de jQuery, tu devrais donc vérifier que tu utilise une version à jour (1.8.1 actuellement).

Cela dit, j'ai un peu trop simplifié la 2e solution car si la requête ajax se complète en moins que 500 millisecondes, tu auras un flash de contenu. Également, `.load()` ne retourne pas une promise (comme les autres requêtes ajax), et donc le callback serait appelé trop tôt encore. Il faudrait donc plutôt faire:


function changerPage( url ) {
	var $conteneur = $("#conteneur");
	
	$conteneur.fadeOut(500)
                .pipe(function() {
			var def = new $.Deferred();
			$conteneur.load(url, dev.resolve);
			return def;
		});
		.then(function() {
			$conteneur.fadeIn(800);
		});
}

Modifié par Vaxilart (19 Sep 2012 - 16:43)