11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous,


Je suis en train de mettre en place un menu javascript/css bien connu d'Alsacreations, voir JS en fin de post.

Le problème que j'ai, c'est que je ne souhaite pas que les sous menus s'ouvrent au chargement de la page. J'ai lu en faisant des recherches que c'était nécessaire pour que le menu reste visible pour les personnes n'ayant pas JS.

Dans mon cas je ne souhaite pas prendre en compte ce paramètre et souhaiterai enlever l'ouverture des sous-menus au chargement de la page.

Je ne suis pas du tout experte en JS et ne sais pas vraiment de quel côté chercher...

Quelqu'un pourrait-il m'apporter son aide svp ?

Merci beaucoup.

Voici le JS en question :


(function() {

var oO =
{
	/**
	 * Label et identifiant du menu associé
	 */
	'Menus': 'menus',


	/**
	 * Labels et intervalles de temps associés
	 */
	'Tempo': 350, // Temps d'ouverture d'un sous-menu (ms)
	'Interval': 10, // Intervalle entre deux itérations de mouvement (ms)


	/**
	 * Label et style associés (définis dans le JS)
	 */
	'Overflow': 'hidden', // sous-menus


	/**
	 * Labels et classes CSS associées (affectées via JS)
	 */
	'Style': 'Surv', // menu
	'Show': 'Montre', // affichage des sous-menus
	'Hide': 'Cache', // masquage des sous-menus
	'FT': 'focusTitle', // entête des sous-menus à la prise de focus
	'BT': 'blurTitle', // entête des sous-menus à la perte de focus

	
	/**
	 * Saleté de navigateur qui ne comprend rien au JS
	 */
	'isSafari': (/webkit/.test(navigator.userAgent.toLowerCase())),


	/**
	 * oO.bTest() -> Teste les méthodes recquises.
	 *               Retourne un booléen
	 */
	bTest: function()
	{
		return document.getElementById && document.getElementsByTagName &&
		document.createElement && document.createTextNode;
	},


	/**
	 * oO.oId(sId) -> Retourne l'élément dont l'id est sId.
	 */
	oId: function(sId)
	{
		return document.getElementById(sId);
	},


	/**
	 * oO.aTag(oEl, sTag) -> Retourne un tableau des éléments
	 *                       nommés sTag et inclus dans l'élément oEl.
	 */
	aTag: function(oEl, sTag)
	{
		return oEl.getElementsByTagName(sTag);
	},


	/**
	 * oO.bElemNotLink(oEl) -> Teste si la valeur de l'élément oEl est non nulle
	 *                         et si c'est un lien.
	 *                         Retourne un booléen
	 */
	bElemNotLink: function(oEl)
	{
		return oEl.nodeValue != null && oEl.nodeName.toLowerCase() != 'a';
	},


	/**
	 * oO.oCreaEl(sTag) -> Retourne un élément nommé sTag.
	 */
	oCreaEl: function(sTag)
	{
		return document.createElement(sTag);
	},


	/**
	 * oO.oCreaTxt(sTxt) -> Retourne un noeud texte de la chaîne sTxt.
	 */
	oCreaTxt: function(sTxt)
	{
		return document.createTextNode(sTxt);
	},


	/**
	 * oO.cancelClick(e) -> Annule la propagation d'un événement
	 */
	cancelClick: 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;
	},


	/**
	 * oO.elem() -> Retourne un élément avec différents attributs et un texte
	 *              inclus.
	 */
	elem: function()
	{
		var aArg = arguments,
		    oElem = oO.oCreaEl(aArg[0]),
		    iI = 2,
		    aTab = aArg.length;

		for(iI; iI < aTab; iI++)
		{
			iI % 2 == 0 ?
				oO.sAtt = aArg[iI] :
				oO.sVal = aArg[iI];

			if(oO.sAtt && oO.sAtt == aArg[iI-1])
				oO.sAtt == 'class' ?
					oElem.className = oO.sVal :
					oElem.setAttribute(oO.sAtt, oO.sVal);
		}
		if(aArg[1] && typeof aArg[1] == 'string' && aArg[1] != '')
		{
			var oText = oO.oCreaTxt(aArg[1]);

			oElem.appendChild(oText);
		}

		return oElem;
	},


	/**
	 * oO.connect(oElem, sEvType, fn, bCapture) -> Attache un événement à une
	 *                                             action.
	 */
	connect: function(oElem, sEvType, fn, bCapture)
	{
		return document.addEventListener ?
			oElem.addEventListener(sEvType, fn, bCapture):
			oElem.attachEvent ?
				oElem.attachEvent('on' + sEvType, fn):
				false;
	},


	/**
	 * oO.getSource(e) -> Récupère la source d'un événement.
	 */
	getSource: function(e)
	{
		return e.target || e.srcElement;
	},


	/**
	 * oO.contains(container, containee) -> Teste si un élément est inclus dans
	 *                                      un autre.
	 */
	contains: function(container, containee)
	{
		if(container && containee)
		{
			var n = containee;

			for(n; n && n != container; n = n.parentNode) {}

			return n;
		}

		return false;
	},


	/**
	 * oO.insertCtrlLinks(oMenus) -> Transforme les entêtes des sous-menus en
	 *                               liens de contrôle.
	 */
	insertCtrlLinks: function(oMenus)
	{
		if(!oMenus)
			return;

		var aLis = oO.aTag(oMenus, 'li'),
		    iI = aLis.length;

		if(iI == 0)
			return;

		while(iI-- > 0)
		{
			var oChildLi = aLis[iI].firstChild;

			if(!oChildLi)
				return;

			if(oO.bElemNotLink(oChildLi))
			{
				var oA = oO.elem('a', oChildLi.nodeValue, 'href', '#ssmenu');

				aLis[iI].replaceChild(oA, oChildLi);
				oO.connect(oA, 'click', oO.cancelClick, false);
			}
		}

		return oMenus;
	},


	/**
	 * oO.initCptMenu(oMenus) -> Définit le comportement du menu en fonction
	 *                           de l'événement et de l'élément affecté.
	 */
	initCptMenu: function(oMenus)
	{
		if(!oMenus)
			return;

		oO.connect(oMenus, 'mouseover', oO.ctrlDisplayOn, false);
		oO.connect(oMenus, 'mouseout', oO.ctrlDisplayOut, false);

		var aA = oO.aTag(oMenus, 'a'),
		    iI = aA.length;

		if(iI == 0)
			return;

		while(iI-- > 0)
		{
			oO.connect(aA[iI], 'focus', oO.ctrlDisplayOn, false);
			oO.connect(aA[iI], 'blur', oO.ctrlDisplayOut, false);
		}

		return oMenus;
	},


	/**
	 * oO.initStyle(oMenus) -> Définit les styles affectés au menu lorsque JS
	 *                         est actif.
	 */
	initStyle: function(oMenus)
	{
		if(!oMenus)
			return;

		oMenus.className = oO['Style'];
		
		var oNext = oMenus.nextSibling;
		
		while(oNext.nodeType != 1)
			oNext = oNext.nextSibling;
		
		oNext.className = 'over';
		
		var aUls = oO.aTag(oMenus, 'ul'),
		    iI = aUls.length;

		if(iI == 0)
			return;

		do
		{
			aUls[--iI].id = 'ssmenu' + iI;
			if(!oO.isSafari) {
				aUls[iI].style.overflow = oO['Overflow'];
				aUls[iI].hauteur = aUls[iI].offsetHeight;
				aUls[iI].style.height = 0;
			}
			aUls[iI].className = oO['Hide'];
		}
		while(iI > 0);

		return oMenus;
	},


	/**
	 * oO.actif() -> Affecte des liens de contrôle, des styles et un comportement
	 *               au menu.
	 */
	actif: function()
	{
		var oMenus = oO.oId(oO['Menus']);

		if(!oMenus)
			return;

		if(oO.insertCtrlLinks(oMenus))
			if(oO.initStyle(oMenus))
				return oO.initCptMenu(oMenus);

		return false;
	},


	/**
	 * oO.ctrlDisplayOn(e) -> Repère l'élément d'où l'événement a été généré et
	 *                        renvoie une demande d'affichage.
	 */
	ctrlDisplayOn: function(e)
	{
		if(e)
		{
			var oRelatedNode = e.fromElement;

			return oO.ctrlDisplay(e, oRelatedNode);
		}

		return false;
	},


	/**
	 * oO.ctrlDisplayOut(e) -> Repère l'élément sur lequel on arrive à la suite
	 *                         d'un événement et renvoie une demande de masquage.
	 */
	ctrlDisplayOut: function(e)
	{
		if(e)
		{
			var oRelatedNode = e.toElement;

			return oO.ctrlDisplay(e, oRelatedNode);
		}

		return false;
	},


	/**
	 * oO.compareSsMenu(oMenus, oUl) -> Retourne le numéro d'ordre du sous-menu
	 *                                  demandé parmi l'ensemble des sous-menus.
	 */
	compareSsMenu: function(oMenus, oUl)
	{
		if(!oMenus || !oUl)
			return;

		var aUls = oO.aTag(oMenus, 'ul'),
		    iI = aUls.length;

		for(; iI >= 0; iI--)
			if(aUls[iI] == oUl)
				return iI;

		return false;
	},


	/**
	 * oO.ctrlDisplay(e, oRelatedNode) -> Contrôle l'affichage / masquage
	 *                                   des sous-menus.
	 */
	ctrlDisplay: function(e, oRelatedNode)
	{
		var oRelatedNode = e.relatedTarget || oRelatedNode,
		    oSource = oO.getSource(e),
		    oMenus = oO.oId(oO['Menus']);

		while(oSource && oSource != oMenus)
		{
			var oUl = oO.aTag(oSource, 'ul')[0],
			    oParentSource = oSource.parentNode,
			    iI;

			if(!oO.contains(oSource, oRelatedNode) && oUl &&
			(iI = oO.compareSsMenu(oMenus, oUl)) != null)
				if(e.type == 'mouseout')
				{
					oO.temp = setTimeout
					(
						function()
						{
              			oUl.parentNode.firstChild.className = oO['BT'];
							oO.deroule(oUl.id, oUl.hauteur, 0, oO['Interval']);
						},
						oO['Tempo']
					);
					if(oSource.PostIt != oO.temp)
						oSource.PostIt = oO.temp;
				}
				else if(oO.temp && oSource.PostIt == oO.temp &&
				e.type == 'mouseover')
				{
					oO.deroule(oUl.id, 0, oUl.hauteur, oO['Interval']);
					oO.PostIt = null;
					clearTimeout(oO.temp);
				}
				else
				{
					switch(e.type)
					{
						case 'mouseover':
							oO.deroule(oUl.id, 0, oUl.hauteur, oO['Interval']);
							break;

						case 'focus':
              			oUl.parentNode.firstChild.className = oO['FT'];
							oUl.className = oO['Show'];
							oUl.style.height = oUl.hauteur + 'px';
							break;

						case 'blur':
             			oUl.parentNode.firstChild.className = oO['BT'];
							oUl.className = oO['Hide'];
							oUl.style.height = 0;
							break;
					}
				}

				if(oSource.nodeName.toLowerCase() == 'a')
					if(e.type == 'focus' || e.type == 'mouseover')
						if(oParentSource.parentNode == oMenus)
							oSource.className = oO['FT'];
					else if(e.type == 'blur' || e.type == 'mouseout')
						if(oParentSource.parentNode == oMenus)
							oSource.className = oSource.className;

				oSource = oParentSource;
		}

		return true;
	},


	/**
	 * oO.deroule(id, initHeight, finalHeight, interval) -> Anime la hauteur
	 *                                                      d'un élément.
	 */
	deroule: function(id, initHeight, finalHeight, interval)
	{
		var oElem = oO.oId(id);
		if(!oElem) return;
		if(oO.isSafari && !oElem.testSafari && oElem.className == oO['Hide']) {
			oElem.className = oO['Show'];
			finalHeight = oElem.offsetHeight;
			oElem.style.height = 0;
			oElem.testSafari = true;
		}
		if(oElem.style.overflow != 'hidden') {
			oElem.style.overflow = 'hidden';
			oElem.style.height = oElem.offsetHeight + 'px';
		}
		if(oElem.movement) clearTimeout(oElem.movement);
		var iDimY = parseInt(oElem.style.height);
		if(iDimY == finalHeight) {
			if(!oElem.test) oElem.test = true;
			else {
				oElem.style.height = '';
				oElem.style.overflow = '';
				oElem.test = null;
				oElem.testSafari = null;
			}
		if(iDimY < 2) {
			oElem.className = oO['Hide'];
		}
			return;
		}
		if(finalHeight != 0) {
			oElem.className = oO['Show'];
		}
		if(iDimY < finalHeight) iDimY = iDimY + Math.ceil((finalHeight - iDimY)/10);
		if(iDimY > finalHeight) iDimY = iDimY - Math.ceil((iDimY - finalHeight)/10);
		oElem.style.height = iDimY + 'px';
		var repeat = function() { oO.deroule(id, initHeight, finalHeight, interval); };
		oElem.movement = setTimeout(repeat, interval);
		return;
	}
};

if(oO.bTest)
	oO.connect(window, 'load', oO.actif, false); // Lancement du script

})();
Bonjour et bienvenu sur le Forum Smiley smile

Sujet déplacé dans le Salon approprié.
Merci d'y faire attention à l'avenir.
A priori, pas besoin de javascript, ajoute simplement la règle CSS pour cacher par défaut les <ul> du menu...
<style type="text/css">
#menus ul {visibility:hidden;}
</style>
Modérateur
Salut,

chadom a écrit :
A priori, pas besoin de javascript, ajoute simplement la règle CSS pour cacher par défaut les <ul> du menu...
<style type="text/css">
#menus ul {visibility:hidden;}
</style>
Au contraire... C'est à Javascript de contrôler l'affichage/masquage des sous-menus afin que ceux-ci restent accessibles lorsque ce langage est indisponible. Smiley cligne

Du coup, tu peux procéder comme suit :

xhtml
<body>
    [#blue]<script type="text/javascript"><!--
           document.body.className += ' hasJS';
       //--></script>[/#]
    <ul id="menus">
        <li>
            <a href="#">liste</a>
            <ul [#blue]class="Cache"[/#]>
                ...
            </ul>
        </li>
    </ul>
</body>


css
[#blue].hasJS[/#] #menus .Cache {display:none;}
Ainsi, si JS n'est pas disponible, les sous-menus restent apparents vu qu'on ne les planque que si la classe "hasJS" est présente...
... et étant donné que la classe "hasJS" est ajoutée avant que le contenu ne soit parsé, les sous-menus n'apparaissent pas au chargement de la page.
Merci pour l'intérêt porté à mon post.

Ne trouvant pas de solution, j'ai préféré changer de menu.

Merci quand même et désolé pour ceux qui auront le même souci...
Modérateur
La solution proposée ci-dessus doit pourtant bien fonctionner.... enfin bon, à toi de voir Smiley rolleyes