11544 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

j'ai réalisé une page sur mon site avec des astuces. J'ai fait un liste et lorsqu'un utilisateur choisit un élément, un bloc en-dessous s'affiche avec le contenu de l'astuce.

Pour cela, j'utilise JQuery avec une fonction lorsqu'il clique sur un élément de la liste et du PHP pour renvoyer l'astuce à afficher.

Je souhaiterai ajouter un effet à cela pour qu'il y ait un effacement/affichage progressif.

J'ai donc essayé avec .fadeIn et .fadeOut mais il y a toujours un problème de synchronisation.

$(function() {
    $('.liste_astuce').click(function() {
        
        if ($('.astuce').is(':visible'))
            $('.astuce').fadeOut("slow");
            
        var no_astuce=$(this).attr('name');
        
        $.post('/fonctions/astuce.php', {no:no_astuce}, function (data) {
            $('.astuce').html('<p class="gras">'+data.titre+'</p><hr /><p>'+data.contenu+'</p>');
        }, 'json');
            
            $('.astuce').fadeIn("slow");
        return false;
    });
});


Dans ce code, si une astuce est affichée, je la cache progressivement, pour ensuite en afficher une nouvelle.

Le problème est que lors du fadeOut, la nouvelle astuce s'affiche déjà, puis se réaffiche ensuite avec le fadeIn.

J'ai essayé avec fadeTo ou en ajoutant empty(), hide()/show() mais cela n'a pas donné de résultat correct.

Merci de votre aide.
Modifié par skurty (05 Apr 2010 - 16:10)
Merci de ta réponse.

Comme tu me l'as conseillé j'ai utilisé $.ajax mais cela ne résout pas mon problème : le bloc s'estompe et le contenu change avant que le bloc ne disparaisse avant de se ré-afficher.

Voici le code avec $.ajax :

$(function() {
    $('.liste_astuce').click(function() {

        var no_astuce=$(this).attr('name');
        
        $.ajax({
            type : 'POST',
            url : '/fonctions/astuce.php',
            data : 'no='+no_astuce,
            dataType: 'json',
            beforeSend : function () {
                if ($('.astuce').is(':visible'))
                    $('.astuce').fadeOut("slow");
            },
            success : function(data) {
                $('.astuce').html('<p class="gras">'+data.titre+'</p><hr /><p>'+data.contenu+'</p>');
                $('.astuce').fadeIn("slow");
            }
        });
        return false;
    });
});


Je mets également le code du fichier PHP si cela peut aider :

<?php

include('../connexion.php');
mysql_query("SET NAMES 'utf8'");

extract($_POST);
if (isset($no)) {
    $requete=mysql_query("select titre, contenu from astuce where no=$no");
    if (mysql_num_rows($requete)) {
        $tab_assoc=mysql_fetch_assoc($requete);
        $res=array(
            'titre'=>$tab_assoc['titre'],
            'contenu'=>$tab_assoc['contenu']
        );
        echo json_encode($res);
    }
    else json_encode('Problème lors de la requête.');
}
else echo json_encode('Problème de paramètre.');
?>


Et la liste ressemble à ça :

<ul>
    <li><a href="#" class="liste_astuce" name="1">Astuce 1</a></li>
    <li><a href="#" class="liste_astuce" name="2">Astuce 2</a></li>
    <li><a href="#" class="liste_astuce" name="3">Astuce 3</a></li>
</ul>

Modifié par skurty (05 Apr 2010 - 15:24)
Salut, il faut utiliser un fonction callback pour l'exécuter après la disparition de l'astuce. Et faire apparaitre l'astuce après avoir modifier son contenu (donc dans $.post).

$(function() { 
    $('.liste_astuce').click(function() { 
         
        var no_astuce=$(this).attr('name'); 
        //la fonction pour faire apparaitre l'astuce
        var fade_in_astuce = function(){
             $.post('/fonctions/astuce.php', {no:no_astuce}, function (data) { 
                 $('.astuce').html('<p class="gras">'+data.titre+'</p><hr /><p>'+data.contenu+'</p>')
                 .fadeIn("slow"); //on affiche l'astuce
             }, 'json'); 
        };
         
        if ($('.astuce').is(':visible'))
            $('.astuce').fadeOut("slow", fade_in_astuce); //fade_in_astuce est exécuter quand fadeOut à fini
        else
            fade_in_astuce();

        return false; 
    }); 
});


La problème c'est que $.post ce déclenche après que .astuce soit cacher. Une méthode serait de passer par une fonction intermédiaire qui n'affiche l'astuce uniquement quand le fadeOut et le$.post sont terminer.
$(function() { 
    $('.liste_astuce').click(function() { 
         
        var no_astuce=$(this).attr('name'),
            dataPost = null, isOut = false,
            fade_in_astuce = function(){
                if (dataPost && isOut)
                    $('.astuce').html('<p class="gras">'+dataPost.titre+'</p><hr /><p>'+dataPost.contenu+'</p>')
                    .fadeIn("slow");
            };

        $.post('/fonctions/astuce.php', {no:no_astuce}, function (data) {
             dataPost = data;
             fade_in_astuce();
        }, 'json'); 
         
        $('.astuce').fadeOut("slow", function(){
             isOut = true;
             fade_in_astuce();
        };

        return false; 
    }); 
});
J'ai trouvé comment faire, en un peu moins compliqué que toi lol :

$(function() {
    $('.liste_astuce').click(function() {
        
        var no_astuce=$(this).attr('name');
        
        $('.astuce').fadeOut("slow", function() {        
            $.post('/fonctions/astuce.php', {no:no_astuce}, function (data) {
                $('.astuce').html('<p class="gras">'+data.titre+'</p><hr /><p>'+data.contenu+'</p>').fadeIn("slow");
            }, 'json');
        });
        
        return false;
    });
});


Il fallait utiliser le callback de fadeOut en fait. Grâce à celui-ci, l'ajax ne se déclenche que lorsque le fadeOut a fini alors que sans ce n'était pas le cas.

Problème résolu donc, merci à vous Smiley cligne
En effet, la solution de passer par le callback de fadeOut est pas mal du tout.
J'image que le .astuce correspond à l'id de ton div.

Merci d'avoir poster ta solution.