11522 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Je précise au préalable que je n'y connais rien en js et que je viens de m'y mettre pour créer un menu. Le voici : menu de navigation (#navigation)

J'arrive à faire replier mes sous-menus, mais je voudrais qu'un seul reste ouvert à la fois, et je n'arrive pas à créer cet effet.

Voici mon code js :

//navigation
$(document).ready(function () {
	$('ul#itemAboutOn').hide();
	$('#itemAbout').click(function () {
	$('ul#itemAboutOn').slideToggle('medium');
    });
});
$(document).ready(function () {
	$('ul#itemProgramOn').hide();
	$('#itemProgram').click(function () {
	$('ul#itemProgramOn').slideToggle('medium');
    });
});
$(document).ready(function () {
	$('ul#itemListenOn').hide();
	$('#itemListen').click(function () {
	$('ul#itemListenOn').slideToggle('medium');
    });
});
$(document).ready(function () {
	$('ul#itemHelpOn').hide();
	$('#itemHelp').click(function () {
	$('ul#itemHelpOn').slideToggle('medium');
    });
});
$(document).ready(function () {
	$('ul#itemContactOn').hide();
	$('#itemContact').click(function () {
	$('ul#itemContactOn').slideToggle('medium');
    });
});
$(document).ready(function () {
	$('ul#itemCercleOn').hide();
	$('#itemCercle').click(function () {
	$('ul#itemCercleOn').slideToggle('medium');
    });
});
$(document).ready(function () {
	$('ul#panel').hide();
	$('#itemConnexion').click(function () {
	$('ul#panel').slideToggle('medium');
    });
});


Merci pour votre éventuel conseil.
Modifié par Olivier C (18 Jun 2012 - 22:57)
Bonjour,

Sans vouloir être rude, ton code n'est pas flexible, et donc le débuger (voir juste l'améliorer) serait une tâche plutôt ardue. Disons qu'il y a beaucoup à faire.

Ainsi, pour commencer, je te conseillerais de regarder du côté de plugins pour réaliser ce genre d'interactions. Par exemple le twitter bootstrap:

http://twitter.github.com/bootstrap/javascript.html#dropdowns

Éventuellement, tu peux lire la source de leur code et essayer de la répliquer ou de l'améliorer à ta propre sauce. Smiley cligne

Si tu as des questions plus précises, n'hésite pas.
Salut olivier Smiley smile

Je rejoins totalement vaxilart...


De plus dropdown est très simple à mettre en place et son habillage est très aisé aussi...

Je l'utilise dans une admin et c'est franchement nickel...

Et tellement plus simple que de partir dans du développement personnalisé sans connaitre Smiley cligne
Vaxilart a écrit :
Sans vouloir être rude, ton code n'est pas flexible, et donc le débuger (voir juste l'améliorer) serait une tâche plutôt ardue. Disons qu'il y a beaucoup à faire.

Oui, tout a fait. Je savait que vous me feriez ce genre de remarque, comme par exemple, au lieu de mettre une ligne de code par sous-menu, j'aurais pu trouver le moyen de factoriser en faisant par exemple : #navigation ul ul... Mais pour l'instant je ne suis pas arrivé à le faire marcher. Je pense aussi me pencher sur le menu accordéon d'alsacréations que j'ai déjà utilisé et que je pourrais adapter sous forme de menu grâce au css... Mais je vais aller voir aussi du côté de votre suggestion.

Quand j'aurais trouvé une soluce je fais un retour ici.

Merci à vous
Modifié par Olivier C (10 Jun 2012 - 23:44)
Bon, comme je suis un mec tétu et que j'ai quand même envie de comprendre un peu le js, j'ai factorisé mon code et ça donne maintenant ceci :
//navigation
$(document).ready(function () {
	$('#navigation ul ul').hide();
	$('#navigation ul+li a').click(function () {
	$('#navigation ul ul').slideToggle('medium');
	});
});

(et oui, c'est beaucoup plus court !)

Le problème, c'est que cette fois-ci, ça ouvre tout ou rien ! Il me reste à trouver comment dérouler seulement le menu correspondant. Je ne dois pas être bien loin de la soluce, non ?
Modifié par Olivier C (11 Jun 2012 - 02:53)
salut, j'ai jeté un coup d'oeil à ton code, et voici ce que je constate d'une part que le javascript ou le jquery ne te sert à rien pour ce que tu veux faire et d'autre part tu ne sais pas faire un menu.

Voici un exemple de menu que l'on peut faire en HTML et CSS.
Il est basique mais fonctionne comme tu le désires.
Lorsque le curseur passe au dessus de onglet, il s'ouvre et lorsqu'il quitte l'onglet, il se referme.
Je reste à ta disposition si tu veux plus d'explication.

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Radio Espérance</title>

<style rel="stylesheet" type="text/css">
ul {
		margin				: 0;
		padding				: 0;
		border				: 0 none;
		list-style			: none;
}

ul > li {
		float				: left;
		position			: relative;
		width				: 170px;
		text-align			: center;
}

ul > li > ul {
		display				: none;
		position			: absolute;
		top					: 20px;
		left				: 0px;
}

ul > li:hover > ul {
		display				: block;
}

ul > li:hover > ul > li {
}

ul > li:hover > ul > li > a {
		display				: block;
		text-align			: center;
		width				: 170px;
		text-decoration		: none;
}

ul > li:hover > ul > li > a:link,
ul > li:hover > ul > li > a:visited,
ul > li:hover > ul > li > a:hover,
ul > li:hover > ul > li > a:active {
		text-decoration		: none;
		color				: black;
}

br.clear {
		clear				: both;
}
</style>
</head>

<body>
	<nav>
		<ul>
			<li>Qui&nbsp;sommes-nous ?
				<ul>
					<li><a href="#01">Présentation</a></li>
					<li><a href="#02">Historique</a></li>
					<li><a href="#03">Lieu de production</a></li>
					<li><a href="#04">Plan d'accès</a></li>
				</ul>
			</li>

			<li>Programme
					<ul>
					<li><a href="#05">Consultez notre programme</a></li>
					<li><a href="#06">Présentation des émissions</a></li>
				</ul>
			</li>

			<li>Nous&nbsp;écouter
				<ul>
					<li><a href="#07">Les Web-Radios</a></li>
					<li><a href="#08">Présentation des émissions</a></li>
					<li><a href="#09">Les fréquences</a></li>
					<li><a href="#10">Par internet</a></li>
					<li><a href="#11">Radio numérique terrestre</a></li>
				</ul>
			</li>
		</ul>
	</nav>

	<br class="clear"/>
</body>
</html>

Modifié par tournikoti (11 Jun 2012 - 08:37)
je ne vois pas pourquoi cela devrait poser problème, s'il est unique dans le document.
Sinon, tu as raison Vaxilart. Je corrige cette bévue.

Revenons au problème de base. Comme je le dis, ce n'est pas un problème de Javascript ou Jquery mais bien un problème HTML et CSS, si justement Olivier C ne sait pas faire un menu.

Je pense qu'il était parti pour faire une usine à gaz !
Modifié par tournikoti (11 Jun 2012 - 08:37)
On peut donner des conseils concernant la création d'un menu. Toutefois, si l'apprentissage d'un langage est souhaitée par un utilisateur, meme si on estime que les techniques utilisées ne sont pas les bonnes on peut tout de même l'aider plutôt que de siplement lui faire remanquer qu'il en sait pas faire un menu.

Je trouve pour ma part qu'un menu javascript n'a rien a envier à un menu HTML/CSS excepté pour les gens désactivant javascript.

Je soutiens Olivier C dans sa démarche d'apprentissage. (au passage jolie factorisation, j'ai eu l'impression de faire des maths de haut niveau).

Pour t'aider, je dirais qu'il existe un $(this) qui gère uniquement l'élément actif. Cela risque d'etre utile dans ton cas.
Modifié par Naemesis (11 Jun 2012 - 09:04)
@ Merci à tournikoti pour son menu css. Mais ce n'est pas ce que je cherche à faire. Je sais faire les menus full css Smiley cligne , j'en ai en stock dans ma bibiothèque perso que je n'utilise plus désormais. En effet, maintenant je code toujours mes thèmes en prévision d'une adaptation pour mobile, et c'est le cas ici (essayez de resizer la fenêtre de votre navigateur, vous verrez).

Je ne veux pas que le menu puisse s'ouvrir au passage de la souris mais seulement sur le click d'un utilisateur, je veux aussi un effet de déploiement du sous-menu, et pour ce faire, jQuery me semble indiqué.

@ Naemesis : merci à toi, ton conseil m'oriente sur l'intuition que je viens de trouver en analysant le menu accordéon du tuto d'Alsacréations avec un ami. Je vais voir de ce côté là.

@ tous : des exemples de toutes sorte, j'en ai récupéré des tones sur le net, tout prêt à l'emploi dans un fichier placé sous MAMP, mais si j'applique à chaque fois un code sans le comprendre, je ne me mettrais jamais sérieusement à jQuery et au js en général, d'où ma démarche.
J'ai analysé son problème et j'ai cru comprendre qu'il avait une difficulté avec son menu.
Et pour remédier à cette difficulté, il recherchait une solution de compensation en jquery.
Du coup ma réaction consistait à dire que la solution ne se trouvait pas dans le jquery mais bien en html & css. Je répète que c'est ce que j'avais compris !

Donc s'il ne veut pas qu'on touche à son menu et qu'il désire une solution minimaliste pour ouvrir et fermer son menu sur un clic, je propose de reprendre mon exemple et de le modifier pour introduire la fonction jquery .click() qui fera cet effet !

J'ai supprimé le hover en css. Du coup ce menu est statique et ne peut être animé qu'avec une fonction jquery. Ne pas oublier de mettre display:none sur le sélecteur "nav ul li ul" pour que cela fonctionne correctement.

J'espère avoir répondu à la question.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Radio Espérance</title>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function ()
{
	$("nav ul li").click(function ()
	{
		$("nav ul li ul").css("display","none");
		$(this).children("ul").toggle();
	});
});
</script>

<style rel="stylesheet" type="text/css">
ul {
		margin				: 0;
		padding				: 0;
		border				: 0 none;
		list-style			: none;
}

ul > li {
		float				: left;
		position			: relative;
		width				: 170px;
		text-align			: center;
}

ul > li > ul {
		display				: none;
		position			: absolute;
		top					: 20px;
		left				: 0px;
}

ul > li > ul > li {
}

ul > li > ul > li > a {
		display				: block;
		text-align			: center;
		width				: 170px;
		text-decoration		: none;
}

ul > li > ul > li > a:link,
ul > li > ul > li > a:visited,
ul > li > ul > li > a:hover,
ul > li > ul > li > a:active {
		text-decoration		: none;
		color				: black;
}

br.clear {
		clear				: both;
}
</style>
</head>

<body>
	<nav>
		<ul>
			<li>Qui&nbsp;sommes-nous ?
				<ul>
					<li><a href="#01">Présentation</a></li>
					<li><a href="#02">Historique</a></li>
					<li><a href="#03">Lieu de production</a></li>
					<li><a href="#04">Plan d'accès</a></li>
				</ul>
			</li>

			<li>Programme
					<ul>
					<li><a href="#05">Consultez notre programme</a></li>
					<li><a href="#06">Présentation des émissions</a></li>
				</ul>
			</li>

			<li>Nous&nbsp;écouter
				<ul>
					<li><a href="#07">Les Web-Radios</a></li>
					<li><a href="#08">Présentation des émissions</a></li>
					<li><a href="#09">Les fréquences</a></li>
					<li><a href="#10">Par internet</a></li>
					<li><a href="#11">Radio numérique terrestre</a></li>
				</ul>
			</li>
		</ul>
	</nav>

	<br class="clear"/>
</body>
</html>

Modifié par tournikoti (12 Jun 2012 - 01:56)
Désolé, je n'ai pas pu répondre en retour car j'ai changé d'oppérateur cette semaine et je n'avais plus internet...

Donc, la soluce : nul besoin de plugin, jQuery a déjà tout ce qu'il faut :

//navigation
$('#navigation div div').hide();
$('#navigation div h2,.upMenu').click(function(){
if($(this).next('#navigation div div:visible').length !=0){
$(this).next('div').slideUp(500);}
else{$('#navigation div div').slideUp(500);
$(this).next('div').slideDown(500);}
return false;});

En fait il faut remplacer la fonction .toggle par l'utilisation des fonctions .slideUp et .slideDown et développer le code en conséquence. Tout est clairement expliqué dans ce très bon tuto vidéo de Grafikart : tuto jQuery

Il me restait ensuite à comprendre comment reconnaitre un sous-menu ouvert***, j'ai largement repris le code du menu accordéon posté sur Alsacréations par Thomas D.

Et voilà, maintenant je comprends un peu le javascript version jQuery, et quand on voit ce que l'on peut faire avec, ça en vaux la peine.

Bien à vous tous

*** La condition : if($(this).next('#navigation div div:visible').length !=0)
Modifié par Olivier C (18 Jun 2012 - 22:56)
Bonjour,

Voilà un code qui est déjà beaucoup mieux et plus flexible.

Je te conseillerais cependant de retravailler tes sélecteurs #navigation div div semble plutôt redondant. Je t'encouragerais donc à utiliser des classes plutôt que des éléments afin de donner un maximum de flexibilité à ton code (que se passe-t-il si tu décide un jour de remplacer les div par des éléments menu ou par des listes non ordonnées ?)

Également, inutile d'écrire tout cela:


if ( $(this).next('#navigation div div:visible').length !=0 ) {


Ceci suffit:


if ( $(this).next('#navigation div div:visible').length ) {


Tout chiffre supérieur à 1 est une valeur qui renverra true dans ce contexte. (de même, 0 et les chiffres inférieurs renverront false)

Ça fait beaucoup alors je vais me retenir pour d'autres conseils. Mais n'hésite pas si besoin
Hello,
Vaxilart a écrit :
Tout chiffre supérieur à 1 est une valeur qui renverra true dans ce contexte. (de même, 0 et les chiffres inférieurs renverront false)

Pas exactement, une expression de type Number n'est transformée en false que pour les valeurs -0, +0 et NaN.
Modifié par Julien Royer (19 Jun 2012 - 09:57)
@Julien Royer: Moi qui avait fait bien attention à cette phrase pour ne pas me faire reprendre Smiley langue

Mais je me suis fait bien prendre, c'est effectivement au delà de 0.
Bonjour aux alsanautes,

Je reviens sur ce sujet car je viens de me rendre compte que mon menu ne marche pas avec IE8 (il ne s'ouvre pas)... et je ne sais pas pourquoi.

En fait, j'hésite entre un problème de compatibilité du code javascript et un problème de positionnement css...

Vraiment je sèche. Merci pour vos suggestions éventuelles.

Edit du 30/08/2012 : évidement, avec un lien sur la page concernée cela irait beaucoup mieux ! Mais je vais ouvrir un sujet dédié à ce problème.

Au cas où, voici le lien de la page du menu (le menu du header) : lien de test

Edit de l'édit : j'ai trouvé : c'est PIE.htc qui fait planter le script... il va peut-être falloir que je fasse un choix... Smiley sweatdrop
Modifié par Olivier C (30 Aug 2012 - 14:37)