Bonjour,

J'ai utilisé le tuto menu déroulant vertical. Un petit problème gênant :

Lorsque ma page se charge, pendant 1/2 seconde le menu est ouvert entièrement puis se ferme une fois la page chargée.
Comment faire pour éviter son ouverture au chargement?
le site: http://poutchak.free.fr/
Merci d'avance Smiley smile
Modifié par Jefiban (19 Jun 2008 - 09:53)
Administrateur
Bonjour et bienvenue,

ce comportement est tout à fait normal: en l'absence de Javascript, il faut que le visiteur puisse accéder à tous les liens du menu et donc par défaut le menu est ouvert, c'est JS une fois chargé qui va fermer le menu (s'il est activé). On parle de JS non obstrusif puisqu'on a pas absolument besoin d'avoir JS d'activé pour utiliser le site.
Comment l'éviter? Tout faire pour charger plus vite ou rajouter une petite animation qui indique au visiteur que quelque chose de transitoire est en train de se passer et qu'il faut qu'il attende la fin du chargement de la page, dans ce genre-là:

upload/39-roueajax.gif

EDIT: Fermer par défaut le menu (en l'absence de JS) nuirait gravement à l'accessibilité de ton site, une décision certainement plus gênante que cette 1/2 seconde d'attente ...
Modifié par Felipe (19 Jun 2008 - 10:56)
ah d'accord!
Effectivement vu comme ça.
Mais...
la demi seconde d'attente n'est pas gênante, ce qui l'est, c'est l'impression que l'image saute. Une petite anim est peut être la solution, mais je vois pas vraiment comment l'intégrer. Js c'est pas mon truc Smiley smile
On peut aussi cacher les sous-menus plus tôt, en utilisant un évènement de type «DOM Ready» plutôt que body.onload qui attend le chargement complet des contenus (images comprises). Les principales bibliothèques JavaScript en proposent un (mais il faut charger la bibliothèque en question Smiley cligne ).

Pour quelque chose d'indépendant d'une bibliothèque, voir par exemple:
http://www.brothercake.com/site/resources/scripts/domready/

On peut aussi utiliser une classe "hasJS" sur l'élément HTML pour cacher les sous-menu si JS est activé. Faire une recherche sur "hasJS" sur le forum.
Merci Smiley smile

Donc je suis tombé sur ça :

a écrit :
styles :


.hasJS .navMenu ul {display:none;}

.hasJS .navMenu li:current {display:block;}



et dans ton JS tout en haut du fichier JS (au tout tout tout début et le fichier JS doit aussi etre appelé dans le <head></head>)
script :



document.documentElement.className+=" hasJS";


de ce sujet : http://forum.alsacreations.com/topic.php?fid=5&tid=35335&s=hasJS

Seulement j'ai du rater un truc, maintenant mon menu ne s'ouvre plus du tout.. Smiley langue

J'ai donc fait ça dans mon css:
.hasJS ul {
display:none;
}
.hasJS li:current {
display:block;
}


et rajouté la ligne dans mon js :
document.documentElement.className+=" hasJS";
Bon après relecture je comprends toujours rien à son exemple de hasJS.

Edit: après un nombre incalculable de lecture je commence à saisir le principe du truc.
je continue ma lecture alors Smiley langue
Modifié par Jefiban (19 Jun 2008 - 16:20)
Modérateur
Salut,

Dans tes styles, il faut mettre :
.hasJS .navMenu ul {display:none;}
.hasJS .navMenu .current ul {display:block;}
et pas :
.hasJS ul {display:none;}
car, dans ce cas, tu agis sur tous les "ul" de ta page.

Dans le JS, tu mets ensuite :
document.documentElement.className += ' hasJS';
ce qui va avoir pour effet d'ajouter la classe hasJS sur l'élément "html" et donc de planquer les "ul" de ton menu au plus vite.

Après, toujours via JS et en fonction des événements, tu ajoutes et tu supprimes la classe "current" sur l'élément "li" qui contient le "ul" :
<ul class="navMenu">
    <li [#blue]class="current"[/#]>
        <a href="section1.html">menu 1</a>
        <ul>
            <li><a href="lien1.html">lien 1</a></li>
            <li><a href="lien1.html">lien 1</a></li>
            <li><a href="lien1.html">lien 1</a></li>
        </ul>
    </li>
</ul>
Rien à faire, j'y arrive pas Smiley decu

Voila mon menu :

<dl id="menu">

		<dt onclick="javascript:montre();"><a href="/index.php">actualités</a></dt>
		<dt onclick="javascript:montre('smenu2');"><a href="/html/presentation.php?ID=smenu2">présentation</a></dt>
			<dd id="smenu2">
				<ul>
					<li id="liens_simples"><a href="#?ID=smenu2">r&ocirc;le</a></li>
					<li id="liens_simples"><a href="#?ID=smenu2">historique</a></li>
					<li id="liens_simples"><a href="#?ID=smenu2">organisation</a></li>
				</ul>
			</dd>	
		<dt onclick="javascript:montre('smenu3');"><a href="/html/equipes.php?ID=smenu3">équipes</a></dt>
			<dd id="smenu3">
				<ul>
					<li id="liens_doubles"><a href="/html/organismes.php?ID=smenu3">organismes membres</a></li>
					<li id="liens_simples"><a href="/html/annuaire.php?ID=smenu3">annuaire</a></li>
				</ul>
			</dd>
...
...
...
</dl>
<script language="JavaScript">window.onload=function(){montre('<?=$_GET[ID]?>');}</script>
Modérateur
Salut,

Dans ton script, tu ne tentes à aucun moment d'appliquer cette méthode... Smiley sweatdrop
Le mieux serait de nous montrer à quel endroit tu bloquais réellement afin qu'on puisse t'aider à repérer ton erreur. Smiley cligne
Bon faut pas se moquer hein Smiley langue

j'ai fais ça (en plus d'autre teste qui je pense n'ont aucun sens):

<ul class="navMenu">
    <li class="current">
		<dt onclick="javascript:montre('smenu2');"><a href="/html/presentation.php?ID=smenu2">présentation</a></dt>
			<dd id="smenu2">
				<ul>
					<li id="liens_simples"><a href="#?ID=smenu2">rôle</a></li>
					<li id="liens_simples"><a href="#?ID=smenu2">historique</a></li>
					<li id="liens_simples"><a href="#?ID=smenu2">organisation</a></li>
				</ul>
			</dd>	
			</li>
			</ul>
Modérateur
Arf... On s'est mal compris. Smiley murf

Le cumul de listes est inutile (sans compter qu'il est incorrect : tu n'as pas de dl pour encadrer tes dt et dd).
Ce qui compte, c'est avant tout de mettre un balisage adapté à ton contenu; ce n'est ni la mise en page ni le comportement à obtenir qui doivent t'influencer.

Bref, je te laisse un exemple complet (par manque de temps) :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	                  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8" />
		<title>Exemple</title>
		<script type="text/javascript"><!--

(function() {

// AJOUT DE LA CLASSE HASJS A L'ELEMENT HTML
document.documentElement.className += ' hasJS';

// GESTION DES EVENEMENTS
var evt = {
	// AJOUT D'UN GESTIONNAIRE D'EVENEMENT
	connect: function(oEl, sEvType, fn, bCapture) {
		return document.addEventListener ?
			oEl.addEventListener(sEvType, fn, bCapture || false):
				oEl.attachEvent ?
					oEl.attachEvent('on' + sEvType, fn):
					false;
	},
	// ANNULATION DE LA PROPAGATION DE L'EVENEMENT ET DE L'ACTION PAR DEFAUT DE LA CIBLE
	stop: function(e) {
		if(e && e.stopPropagation && e.preventDefault) {
			e.stopPropagation();
			e.preventDefault();
		}
		else if(e && window.event) {
			window.event.cancelBubble = true;
			window.event.returnValue = false;
		}
		return false;
	}
};

// GESTION DES CLASSES CSS
var css = {
	remove: function(oEl, sClass) {
		var rep = oEl.className.match(' ' + sClass) ? ' ' + sClass : sClass;
		oEl.className = oEl.className.replace(rep, '');
	},
	add: function(oEl, sClass) {
		if(!css.has(oEl, sClass)) oEl.className += oEl.className ? ' ' + sClass : sClass;
	},
	has: function(oEl, sClass) {
		return new RegExp('\\b' + sClass + '\\b').test(oEl.className);
	}
};

// SCRIPT DU MENU
var menu = {
	label: 'menu',
	// REINITIALISATION DU MENU
	init: function(aEls, oEl) {
		if(!aEls || !oEl) return;
		var iEl = aEls.length;
		while(iEl-- > 0) {
			if(aEls[iEl] == oEl) continue;
			css.remove(aEls[iEl], 'current');
		}
	},
	// SELECTION DES SOUS-MENUS
	selectSsMenus: function() {
		var aUls = document.getElementsByTagName('ul');
		var iUl = aUls.length;
		var aLis;
		while(iUl-- > 0)
			if(css.has(aUls[iUl], menu.label))
				aLis = aUls[iUl].getElementsByTagName('li');
		return aLis;
	},
	// AJOUT DES GESTIONNAIRES D'EVENEMENTS SUR LES LIENS DE CHAQUE ITEM DE LISTE
	addBehaviour: function(aEls) {
		if(!aEls) return;
		var iEl = aEls.length;
		var oA;
		while(iEl-- > 0) {
			oA = aEls[iEl].getElementsByTagName('a')[0];
			if(!oA) continue;
			evt.connect(oA, 'click', (function(oEl) {
				return function(e) {
					menu.init(menu.selectSsMenus(), oEl);
					css[css.has(oEl, 'current') ? 'remove' : 'add'](oEl, 'current');
					return oEl.getElementsByTagName('ul')[0] ? evt.stop(e) : true;
				}
			})(aEls[iEl]));
		}
	}
};

// CHARGEMENT DU SCRIPT
evt.connect(window, 'load', function() {
	var aSsMenus = menu.selectSsMenus();
	menu.addBehaviour(aSsMenus);
});

})();

		//--></script>
		<style type="text/css"><!--

@media screen, projection {
	.menu,
	.menu ul {margin:0; padding:0;}
	.menu li {list-style-type:none;}
	.menu a {display:block; width:9em; line-height:1.3em; padding:3px 5px; background:#66d; color:white; text-decoration:none;}
	.menu a:hover,
	.menu a:focus,
	.menu a:active,
	.menu .current a {background:#463;}
	.menu ul a,
	.menu .current ul a {background:#439;}
	.menu ul a:hover,
	.menu ul a:focus,
	.menu ul a:active {background:#943;}
	.hasJS .menu ul {display:none;}
	.hasJS .menu .current ul {display:block;}
}

		--></style>
	</head>
	<body>
		
<ul class="menu">
    <li class="current">
        <a href="section1.html">menu 1</a>
        <ul>
            <li><a href="lien11.html">lien 1.1</a></li>
            <li><a href="lien12.html">lien 1.2</a></li>
            <li><a href="lien13.html">lien 1.3</a></li>
        </ul>
    </li>
    <li>
        <a href="section2.html">menu 2</a>
        <ul>
            <li><a href="lien21.html">lien 2.1</a></li>
            <li><a href="lien22.html">lien 2.2</a></li>
            <li><a href="lien23.html">lien 2.3</a></li>
        </ul>
    </li>
</ul>
		
	</body>
</html>
- côté JS, tu n'as rien à faire,
- côté CSS, il faut adapter ce que j'ai fait à tes besoins,
- et côté structure, il faut respecter la même syntaxe sachant que si tu mets une classe "current" comme dans cet exemple, le sous-menu sera ouvert au chargement.

En surplus, il y a la technique du hasJS. Smiley cligne

PS: Tu peux mettre le JS et le CSS dans des fichiers externes.
Modifié par koala64 (25 Jun 2008 - 19:30)
ok merci, en effet ça marche Smiley smile

Le seul petit soucis c'est qu'une fois cliqué sur un lien, le menu se referme.
Modérateur
En quoi est-ce un soucis ? Smiley sweatdrop

Souhaites-tu qu'on ne puisse fermer un sous-menu déjà ouvert en recliquant dessus ou plutôt que lorsque tu cliques sur un sous-menu, cela ne ferme pas d'autres déjà ouverts ou encore que tous puissent se fermer excepté le menu courant ?

A vrai dire, plusieurs comportements sont envisageables et là ben... t'as le plus souple (donc celui qui crée le moins de frustration chez l'utilisateur).
Modifié par koala64 (27 Jun 2008 - 20:25)
Salut à tous et merci pour ce très bon site qui aide des milliers de webmaster en détresse (comme moi Smiley lol )

J'ai précisement le même soucis que Jefiban alors j'ai un peu cherché et je pense avoir trouvé.

Je dis peut être une grosse connerie mais j'ai réussi, apparement à résoudre très facilement le probleme en ajoutant ceci apres la
</div>
du code original du menu déroulant donné sur ce site.


<script type="text/javascript">
window.onfocus=montre('');
</script>


Et en virant le (mais ce n'est pas obligatoire)

windows.onload=montre;


du javascript...

En tout cas chez moi ca (semble) marche(r) sur IE et FF, sous FF on ne voit même pas les menus au chargement. Sous IE ils apparaissent une fraction de seconde.

Si jamais il y a des raison de ne pas utiliser cette méthode merci de le faire savoir Smiley smile


ps: un hopla à tous les alsaciens d'un alsacien expatrié en Belgique (les meilleurs Smiley lol )
Modifié par Econologie (02 Jul 2008 - 18:10)