11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

voici (encore) un nouveau sujet sur le menu en accordéon. Mon menu marche. Sauf que quand je clique, par exemple, sur le dernier menu, les sous-menu se développent sans scrolling (normal !). Je voudrais donc effectuer un scroll pour afficher en haut de mon id moleculemenu le menu qui a été ouvert et quand je reclique sur le menu ouvert (qui se ferme) faire un scroll down pour réafficher l'ensemble du menu.

Voici le code html5 pour la déclaration du menu :

...
<aside ><!-- sidebar -->
	<div id="moleculemenu" > <!-- div contenant mon menu -->
	<h3>232 mol&eacute;cules</h3> <!-- nombres de données dans la base -->
              <div id="firstpane" class="menu_list"> <!-- début de mon menu -->
                     <p class="menu_head">alcanes</p> <!-- premier élément du menu -->
                             <div class="menu_body"> <!-- début du sous menu -->
                                 <a href="#" onclick="[i]une fonction[/i]">CH<sub>3</sub>-CH<sub>3</sub></a>
                                 <a href="#" onclick="[i]une fonction[/i]">CH<sub>3</sub>-CH<sub>3</sub> ecl</a>
                                 <a href="#" onclick="[i]une fonction[/i]">CH<sub>4</sub></a>
                                 <a href="#" onclick="[i]une fonction[/i]">cyclopropane</a>
                             </div>                           <!-- fin du sous menu -->
...
           </div>
</aside>

avec le css du menu :


 a {
  color:#000;
  text-decoration:none;
}
.menu_list {	
	margin:0;
  padding:0;
  width:220px;
  list-style-type:none;
  line-height:120%;
}
.menu_head {
	cursor: pointer;
	margin:0px;
  font-weight:normal;
  background: #2F527A url(ha-down.gif);
  background-position:98% 50%;
  background-repeat:no-repeat;
  color: #faf0e6;
 
  padding:7px ;
  padding-left:20px;
}
.menu_head:hover, .menu_all:hover {
  text-decoration: underline;
color: #b0c4dd;
}

.menu_body {
	display:none;
}
/* sous menu */
.menu_body a{ 
  display:block;
  font-weight:normal;
  text-decoration:none;
  padding:4px 6px 6px 30px;
  border-top:1px solid #696969;
  border-left:10px solid #696969;
  border-right:1px solid #8A8A8A;
  border-bottom:1px solid #7B7B7B;
  background-color:#ffc66d; /* orange */
  color:#000000;
}
.menu_body a:hover{/* liens du sous-menu */
  background-color:#ac8b68; /* marron */
  color:#FFFFFF;
  text-decoration:none;
}

et le css de moleculemenu :

#moleculemenu {
margin-top: 10px;
height: 610px;
float: left;
padding-left: 20px;
width: 20em;
padding-bottom: 25px;
overflow: auto;
}


Avec un petit script java que j'ai trouvé, je peux gérer le menu :

 $("#firstpane p.menu_head").click(function()
           {
                var img;
                if ($(this).next("div.menu_body").is(':visible')) {
                     img = "url(./script/menu/ha-down.gif)";
                } else {
                     img = "url(./script/menu/ha-up.gif)";
                };
                $(this).css({backgroundImage:img}).next("div.menu_body").slideToggle(300).siblings("div.menu_body").slideUp("slow");
                $(this).siblings().css({backgroundImage:"url(./script/menu/ha-down.gif)"}); 
           });



une idée ?

A+
Furax
Modifié par furax (08 Jul 2012 - 09:02)
bon j'ai essayé de rajouter un scrollTo mais rien n'y fait : ça ne bouge pas ! une idée ?

           $("#firstpane p.menu_head").click(function()
           {
                var img;
                var scroll=false;

                if ($(this).next("div.menu_body").is(':visible')) {
                     img = "url(./script/menu/ha-down.gif)";
                } else {
                     img = "url(./script/menu/ha-up.gif)";
                     scroll=true;
                };
                $(this).css({backgroundImage:img}).next("div.menu_body").slideToggle(300).siblings("div.menu_body").slideUp("slow");
                $(this).siblings().css({backgroundImage:"url(./script/menu/ha-down.gif)"}); 
                if (scroll)
                  {
                    var $target = $('#moleculemenu');
                    var targetOffset = $target.offset().top;
                    alert(targetOffset)
                    $(this).animate({ fontSize: "20px"  }, 500 );
                    $(this).siblings().animate({ fontSize: "14px" }, 100 );

                    $('#fistpane').animate({scrollTop:targetOffset}, 300);
                    
                  }
           });

Modifié par furax (06 Jul 2012 - 09:22)
Pour voir en direct ce que je veux faire c'est ici. Dans le menu horizontal choisir "Base de Données". Le menu vertical en accordéon va s'afficher à gauche.

QQ a des idées ?
Modifié par furax (06 Jul 2012 - 11:56)
J'ai trouvé la solution (non sans mal !) avec la fonction .animate() de jquery. J'ai testé ce code sour IE9, Chrome20, FF13, Opéra12 ... ça marche !

Voici le code :

           
           var TotalOffset = new Array(); // stocke tous les offset's des éléments fermés

           $("#firstpane p.menu_head").click(function()
           {
                var img;
                //faire le scroll si un élément du menu est ouvert
                var scroll=false;
                
                //offset de l'élément cliqué
                var targetOffset = $(this).offset().top; 

                //offset de mon div contenant mon menu
                var targetMol = $('#moleculemenu').offset().top; 
                var diff=0;
                var index=0;

                //recherche de tous les offset's tant que le menu est fermé
                $("#firstpane p.menu_head").each(function(){
                      TotalOffset.push($(this).offset().top);
                })
                
                // une solution pour rechercher l'index de l'élément cliqué    
                var text = $(this).text();
                var Research = true;
                var i=0;

                $("#firstpane p.menu_head").each(function(){
                  if (Research && ($(this).text() == text)) {index=i; Research=true;}
                  i++;
                })
                
                // on change l’icône
                if ($(this).next("div.menu_body").is(':visible')) {
                     //menu déjà ouvert donc pas de scroll
                     img = "url(./script/menu/ha-down.gif)";
                     scroll=false;
                } else {
                    //on a cliqué sur un menu fermé donc scroll
                     img = "url(./script/menu/ha-up.gif)";
                     scroll=true;
                };

                // on change l’icône et on développe les sous sections du menu cliqué
               $(this).css({backgroundImage:img}).next("div.menu_body").slideToggle(300).siblings("div.menu_body").slideUp("fast");
                //pour les autres éléments (non ouverts) on change les icônes
                $(this).siblings().css({backgroundImage:"url(./script/menu/ha-down.gif)"});           
                
                // voici ce le moment tant attendu ...     
                if (scroll)
                  { 
                    // on calcule la différence pour effectuer le scroll
                    diff = TotalOffset[index] - targetMol;
                    // on effectue le scroll par une .animate(scrollTop ...)
                    $('#moleculemenu').animate({scrollTop:diff}, {duration: 300, queue: false});
                  }
                  
           });
Pour finaliser ce sujet, je vous donne mon script php pour créer automatiquement le menu ...
ma base de données est dans le répertoire gfiles. Dans ce répertoire, j'ai créé des répertoires (menu) contant des liens qui pointent vers les fichiers (../ ou ./gfiles).



<?php
mb_internal_encoding("UTF-8");
$dir_nom = realpath('gfiles')."/";
$dir = opendir($dir_nom) or die("Erreur de listage : le répertoire n\"existe pas");
$dossier= array();
$fichier= array();
$molecule=array();



// stocke tous les répertoires contenu dans ./gfiles
while($element = readdir($dir))
{
        if ($element != "." && $element != "..")
        {
                if (is_dir($dir_nom."/".$element))
                {
                                $dossier[] = $element;
                }
    }
}

closedir($dir);

// classe par ordre alphabétique croissant
sort($dossier);

//compte tous les liens = nb de molécules
foreach($dossier as $x)
{
        $chemin=$dir_nom."/".$x;
        $x = str_replace("_", " ", $x);
        $y = opendir($chemin) or die("Erreur de listage : le répertoire n\"existe pas");
        while($mol = readdir($y))
        {
                if ($mol != "." && $mol != "..")
                {
                        $link=readlink($chemin.'/'.$mol);
                        $link=str_replace("../", "", $link);
                        $fichier[]=$link;
                }
        }
        closedir($y);
}
$fichier=array_unique($fichier);
$num=count($fichier);


echo "<h3>".$num." mol&eacute;cules</h3>\n";

//
// création du menu
//
echo "<div id=\"firstpane\" class=\"menu_list\">\n";

foreach($dossier as $x)
{
        $chemin=$dir_nom."/".$x;
        $x = str_replace("_", " ", $x);
        $x = utf8_encode($x);
        
        $y = opendir($chemin) or die("Erreur de listage : le répertoire n\"existe pas");
        unset($molecule);
        $nbmol=0;
        while($mol = readdir($y))
        {
                if ($mol != "." && $mol != "..")
                {
                        $molecule[] = $mol;
                }
        }
        
        closedir($y);
        // je mélange
        natsort($molecule);
        // je trie ...
        $array_lowercase = array_map('strtolower', $molecule);
        array_multisort($array_lowercase, SORT_ASC, SORT_STRING, $molecule);
        
        $MolTot = count($molecule);
        echo "   <p class=\"menu_head\">".$x."</p>\n";
    
        echo "      <div class=\"menu_body\">\n";
        echo "      <span class=\"notranslate\">\n";
        //while($mol = readdir($y))

        $i = 0;

        foreach($molecule as $mol)
        {
                if ($mol != "." && $mol != "..")
                {
                        $i++;
                        $link=readlink($chemin.'/'.$mol);
                        // wampserver
                        $wampserver= str_replace($dir_nom, "", $link);                        
                        $link=str_replace("../", "", $link);
                        //$fichier[]=$link;
                  
                        $mol = str_replace("{", "<sub>", $mol);
                        $mol = str_replace("}", "</sub>", $mol);
                        $mol = str_replace("[", "<sup>", $mol);
                        $mol = str_replace("]", "</sup>", $mol);
                        $mol = str_replace("_", " ", $mol);
                        $test = explode(" ", $x);

                        if ($i == 1)
                        {
                            $FirstDiv = "<div class=\"first\">";
                            $EndDiv = "</div>";
                        }
                        else if ($i == $MolTot)
                        {
                            $FirstDiv = "<div class=\"end\">";
                            $EndDiv = "</div>";
                        }
                        else
                        {
                            $FirstDiv = "";
                            $EndDiv = "";
                        }

                        if ($test[0] == "vibrations")
                        {
                                 echo "      ".$FirstDiv." <a href=\"#\" onclick=\"javascript:affiche_freq('".$link."','".$mol."')\">".$mol."</a>".$EndDiv."\n";
                                
                        }
                        else if ($test[0] == 'approche')
                        {
                                 echo "    ".$FirstDiv."  <a href=\"#\" onclick=\"javascript:affiche_topol('".$link."','".$mol."')\">".$mol."</a>".$EndDiv."\n";
                         }
                        else
                        {
                               echo "     ".$FirstDiv." <a href=\"#\" onclick=\"javascript:affiche_jmol('".$link."','".$mol."')\">".$mol."</a>".$EndDiv."\n";
                                
                        }
                }
        }
      
        echo "      </span>\n";
        echo "      </div>\n";
   
}

echo "</div>\n";

?>