11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Suite à cette demande d'aide (cf. ici), je vais essayer de me lancer dans quelques lignes de code JS. Mais mon niveau est bien mince. Après en avoir discuté avec ElMoustiko (qui n'a pas le temps), j'aimerai savoir si quelqu'un peut suivre mes efforts, pas à pas, dans le développement d'un petit menu vertical en JS. Menu qui éviterai le clignotement sous Firefox ? Je ne demande pas du code tout fait (je veux comprendre ce qui se passe) mais une aide du genre : quel instruction utiliser ; la logique est-elle la bonne ; etc.

Si cela intéresse quelqu'un...

Ensuite, cela pourrait devenir un petit tutoriel pour débutant (comme moi).

Cordialement,

GS.
Modifié le 04 Dec 2004 - 18:24
Dans ces conditions, je me lance.

Objectif : un menu vertical cumulant CSS/JS. Ce menu se "déroule" sur un seul niveau (un seul niveau de sous-menus) au passage de la souris.

Avant le code, j'aimerai commencer à résumer ce que doit faire le code JS :
1- vérifier que JS est actif sur le client ;
a. si c'est le cas, cacher l'ensemble des sous-menus (sinon, ils restent visibles) ;
b. si ce n'est pas le cas, montrer tous les sous-menus et modifier les propriétés de la liste du sous-menu pour un alignement correct;
2- une partie du code se déclanche ensuite au passage de la souris. On gère la position d'origine de la souris pour éviter le clignotement sous Firefox :
a. au passage du menu au sous-menu, pas de changement de la propriété display ;
b. au passage d'une partie du sous-menu à une partie du même sous-menu, pas de changement de la propriété display ;
c. au passage d'un menu à un autre, changement de la valeur display".

Que faut-il ajouter d'autre ?

Cordialement,

GS.
Pour la partie (1. a.), je reprends simplement le code déjà vu par El Moustiko :

window.onload = cache_si_JS_actif;
	/* Si JS est actif chez le client, la fonction cache_si_JS_actif est appelée.
	Dans le cas contraire, rien ne se passe.*/

function cache_si_JS_actif(){
	for (var i = 1 ; i <= 4 ; i++) {
	document.getElementById('smenu'+i).style.display='none';
	}
}


Pour le (1. b.)

J'aimerai compléter cette fonction avec les éléments suivants :
- modifier le "heigt", le "margin-top", etc., en même temps que le display ;
- compter le nombre d'id dans le document (dans le but de rendre le menu compatible avec un environnement dynamique). Quelles sont les instructions à mettre en oeuvre ?
Cette fonction elle est pourrie, utilise pas mon tuto, il est naz, la source JS est pas extraite, prend plutot base sur celui de Jep (webdev.ibilab).
Ton principale problème va résider dans le fait de vouloir afficher les sous-menu si le Javascript est desactivé et de la cacher si JavaScript est activé.

Si tu utilise une commande JavaScript pour réalisé cette operation, tu va te heurter en permanence a ton problème de clignotement (car la commande JavaScript ne sera lancé qu'après l'affichage de ta source HTML). Pour eviter ce problème, le plus simple et d'utiliser la balise <noscript> avec une feuille CSS spécial pour le cas ou le JavaScript est desactivé :


<link href="lacssqui_masque_lessousmenus.css" rel="stylesheet" type="text/css" />

<noscript>
<link href="lacssqui_affiche_lessousmenus.css" rel="stylesheet" type="text/css" />
</noscript>


De cette manière, les navigateur seront quoi faire de ton menu avant que celui-ci soit affiché Smiley cligne
Modifié le 29 Nov 2004 - 20:43
@Jep, plutot que de 2 faire feuille quasi identique, il serait plus judicieux de faire

<noscript>
  <style type="text/css">
  /* les styles si JS inactif */
  </style>
</noscript>
C'est exactement la même chose ElMou. Smiley cligne

Dans la deuxième feuille de style, on peut parfaitement ne mettre que les styles à changer. Smiley smile

Perso, je préfère externaliser tous ce qu'il est possible d'externaliser (c'est plus facile pour la maintenance)
Wé, nan mais t'as raison, j'ai encore dis n'importe quoi Smiley confus
En fait je "lisais" remplacer une feuille par une autre... désolé hein lol !!!
Ok. Bien compris la solution du <noscript>. Très habile.

Simple curiosité, je continue avec mes questions :
- peut-on modifier autre chose que le display avec JS (j'imagine que oui). Où trouver les instructions correspondantes ?
- peut-on créer un tableau scalaire contenant les "id" du document ?

Merci. Dès ce-soir/demain, j'essaie d'adapter le script de Jep.

GS.
gsaunier a écrit :
peut-on modifier autre chose que le display avec JS (j'imagine que oui). Où trouver les instructions correspondantes ?

Oui, c'est possible. On peut modifier toutes les propriété CSS via JS. Pour cela, il suffit de faire :
document.getElementById('iddutrucàmodifier').style.nomdelapropriété = "valeurdelaprorpiété";


Pour les propriété CSS contenant un trait d'union "-", il faut remplacer celui-ci par la majuscule du mot suivant :

background-image => backgroundImage
z-index => zIndex
etc...


gsaunier a écrit :
peut-on créer un tableau scalaire contenant les "id" du document ?


Oui, tu peut même créer des tableaux contenant directement les références vers les objets qui t'interressent.
Par exemple, si tu as un tableau HTML avec 10 TD, plutot que de donner un ID à chaque TD et de les mémoriser dans un tableau scalaire, tu peut directement faire :

montableauscalaire = document.getElementByTagName('td');


Puis, pour modifier les propriété CSS d'une des cellules (la 3eme par exemple)

montableauscalaire[2].style.lapropriétéàchanger = "lavaleurdelapropriété"
Vraiment, JEP : un grand merci pour ces explications. Je vais essayer quelques combines. Je vous tiens au courant.

GS (le débutant)

montableauscalaire = document.getElement[#red]s[/#]ByTagName('td');


Attention à ne pas oublier le "s" car les élément récupérés sont multiple (contrairement à getElementById)

Tu peux aussi faire une boucle for pour t'occuper de TOUS les td
Modifié le 01 Dec 2004 - 13:09
Cher Jep,

J'ai réussi à implémenter ton code sur une page de mon site (sous SPIP ; cf. ici). Je voudrai toutefois être certain de bien avoir compris la logique. J'ai donc repris ton code et ajouté des commentaires.

<!--

function setHover()
{
	LI = document.getElementById('menu').getElementsByTagName('li'); /* Récupère et inscrit dans le tableau LI les éléments li du document contenu dans le style "menu" */
	nLI = LI.length; /* Compte le nombre de lignes du tableau LI */
	for(i=0; i < nLI; i++) /* Exécute une boucle sur chaque élément du tableau */
	{
		LI[i ].onmouseover = function() /* Si l'un des éléments du LI est survolé, lance la fonction hover sur cet élement */
		{
			hover(this);
		}
		LI[i ].onmouseout = function() /* Si l'un des éléments du LI n'est pas survolé, lance la fonction hover sur cet élement */
		{
			hover(this);
		}
	}
}

function hover(obj_jojo)
{
	if(document.all) /* Vérifie que le navigateur est IE ou Opera. Si ce n'est pas le cas, le script n'est pas exécuté */
	{
		UL = obj_jojo.getElementsByTagName('ul'); /* Crée un tableau contenant l'ensemble des éléments UL de l'élément survolé dans la fonction setHover */
		if(UL.length > 0) /* Vérifie que le tableau n'est pas vide, c'est à dire qu'il y a bien des tag UL dans cet élément */ 
		{
			sousMenu = UL[0].style; /* Récupère le style de la première balise UL de l'élément survolé dans la fonction setHover  */
			if(sousMenu.display == 'none' || sousMenu.display == '') 
			{
				sousMenu.display = 'block'; /* Si la propriété CSS display de cette balise UL est nulle ou "none", elle est passée en "block" */
			}
			else
			{
				sousMenu.display = 'none'; /* Dans le cas contraire, place cette même valeur sur "none" */
			}
		}
	}
}

-->


Tout ceci est-il correct ? D'avance...

GS.
gsaunier a écrit :
/* Récupère et inscrit dans le tableau LI les éléments li du document contenu dans le style "menu" */

... les éléments li du contenu dans l'élément ayant pour ID "menu"

gsaunier a écrit :
/* Exécute une boucle sur chaque élément du tableau */

La boucle parcourt le tableau LI et applique la fonction pour chaque ligne du tableau

gsaunier a écrit :
/* Si l'un des éléments du LI est survolé, lance la fonction hover sur cet élement */

Au survol de la souris sur l'un des <li> contenu dans le tableau LI, on lance la fonction hover

gsaunier a écrit :
/* Si l'un des éléments du LI n'est pas survolé, lance la fonction hover sur cet élement */

Lorsque la souris quitte l'un des <li>, on lance la fonction hover

gsaunier a écrit :

/* Vérifie que le navigateur est IE ou Opera. Si ce n'est pas le cas, le script n'est pas exécuté */

Juste IE non ? (Jep confirmera ou non), Opera utilise la pseudo class :hover sur autre chose que <a> je pense.

gsaunier a écrit :
sousMenu.display = 'block'; /* Si la propriété CSS display de cette balise UL est nulle ou "none", elle est passée en "block" */

Perso, je mettrais = '' ; plutot que = 'block'.
Vaut mieux pas faire sousMenu.style.display ? plutot que sousMenu.display, je me demande même si sousMenu.display fonctionne.
Modifié le 02 Dec 2004 - 18:39
Merci de tes réponses, El Moustiko. C'est plus précis, mais j'avais bien pigé le truc.

Pour ce qui est du .display, chez moi, cela fonctionne.

Cordialement,

GS.

p.s. Une indication pour mon post sur le CSS ?