11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

J'ai installé sur mon site un menu horizontal qui se base sur Jquery et evidemment du css. J'aimerais que le sous-menu qui porte la classe open_at_load soit ouvert par défaut au chargement de la page.
Ci-dessous tous les codes :

<ul id="topnav">
    <li><a href="#">Link</a></li>
    <li>
        <a href="#">Link</a>
        <!--Subnav Starts Here-->
        <span class="open_at_load">
            <a href="#">Subnav Link</a> |
            <a href="#">Subnav Link</a> |
            <a href="#">Subnav Link</a>
        </span>
        <!--Subnav Ends Here-->
    </li>
    <li><a href="#">Link</a></li>
</ul>


ul#topnav {
	margin: 0; padding: 0;
	float: left;
	width: 970px;
	list-style: none;
	position: relative; /*--Set relative positioning on the unordered list itself - not on the list item--*/
	font-size: 1.2em;
	background: url(topnav_stretch.gif) repeat-x;
}
ul#topnav li {
	float: left;
	margin: 0; padding: 0;
	border-right: 1px solid #555; /*--Divider for each parent level links--*/
}
ul#topnav li a {
	padding: 10px 15px;
	display: block;
	color: #f0f0f0;
	text-decoration: none;
}
ul#topnav li:hover { background: #1376c9 url(topnav_active.gif) repeat-x; }
/*--Notice the hover color is on the list item itself, not on the link. This is so it can stay highlighted even when hovering over the subnav--*/
ul#topnav li span {
	float: left;
	padding: 15px 0;
	position: absolute;
	left: 0; top:35px;
	display: none; /*--Hide by default--*/
	width: 970px;
	background: #1376c9;
	color: #fff;
	/*--Bottom right rounded corner--*/
	-moz-border-radius-bottomright: 5px;
	-khtml-border-radius-bottomright: 5px;
	-webkit-border-bottom-right-radius: 5px;
	/*--Bottom left rounded corner--*/
	-moz-border-radius-bottomleft: 5px;
	-khtml-border-radius-bottomleft: 5px;
	-webkit-border-bottom-left-radius: 5px;
}
ul#topnav li:hover span { display: block; } /*--Show subnav on hover--*/
ul#topnav li span a { display: inline; } /*--Since we declared a link style on the parent list link, we will correct it back to its original state--*/
ul#topnav li span a:hover {text-decoration: underline;}


<script type="text/javascript">
$(document).ready(function() {
         $("span.open_at_load").show();
	$("ul#topnav li").hover(function() { //Hover over event on list item
		$(this).css({ 'background' : '#1376c9 url(topnav_active.gif) repeat-x'}); //Add background color and image on hovered list item
		$(this).find("span").show(); //Show the subnav
	} , function() { //on hover out...
		$(this).css({ 'background' : 'none'}); //Ditch the background
		$(this).find("span").hide(); //Hide the subnav
	});

});
</script>

Modifié par Unbaraki (14 Aug 2009 - 12:44)
Salut,

Tu peux tenter de mettre ton show() qui est sur ton span après les deux autres fonctions.
C'est peut être ça ^^.
Comme ça ? Si oui c'est bien essayé mais ça ne marche pas Smiley smile

<script type="text/javascript">
    <!--
	 $("ul#topnav li").hover(function() { //Hover over event on list item
		$(this).css({ 'background: #1376c9 url(http://localhost/drupal/sites/all/themes/zen/zen_classic/images/background-menu-active.png) repeat-x;'}); //Add background color and image on hovered list item
		$(this).find("span").show(); //Show the subnav
	} , function() { //on hover out...
		$(this).css({ 'background' : 'none'}); //Ditch the background
		$(this).find("span").hide(); //Hide the subnav
	});
	$("span.open_at_load").show();
});
    // -->
    </script>
Et si tu fais un alert de ton $("span.open_at_load") , il te donne quelque chose ?
Un alert($("span.open_at_load")); juste après que le dom soit chargé.
Si il te sort un "undefined" c'est qu'il n'arrive pas à trouver l'élément dans la page, et là ya déjà un petit problème Smiley cligne
Effectivement le problème doit venir de là (ou bien je n'ai pas rajouté le alert où il fallait). Je l'ai mis sur la même page mais dans un script javascript séparé.

J'ai alors une alerte : object Object ... c'est pas undefined mais c'est tout de même sympathique Smiley langue
Bon bein au moins il trouve ton élément....
Mais je crois que je viens de voir ton problème, enfin je peux me tromper. Tu lui dis d'afficher le span alors que dans tes autres fonctions tu affiches le li, la solution serait de mettre la classe sur le li et de mettre li.open_at_load dans ta fonction, ça vient peut être de ça ^^. Si tu avais utilisé Prototype je t'aurais dis de laisser la class et de faire :

   $("span.open_at_load").up('li').show();


Peut être qu'il y a l'équivalent en jQuery mais je ne connais pas assez bien cette libraire pour te le dire.
EDIT: Ah bah voilà en jquery ce serait :

$("span.open_at_load").parent('li').show();

Modifié par N-J (14 Aug 2009 - 16:08)
Merci beaucoup pour ton aide... même si ça ne marche pas Smiley sweatdrop
En fait je ne m'y connais pas du beaucoup en javascript... mais plus je regarde le code plus j'ai l'impression qu'il ne sert a rien ! Je dis peut-être une bêtise mais j'ai l'impression que c'est le css qui fait tout.

Du coup j'ai ajouté dans le css :
ul#topnav li span.open_at_load {
	display: block;
}


Évidemment ça marche mais du coup je me pose deux questions :
- a quoi sert le javascript dans l'histoire (corriger un bug d'ie peut-être Smiley ohwell ?) ?
- est-ce qu'il n'y a pas un problème d'accessibilité en utilisant simplement le css ?

Voilà... j'attends vos réponses pour rajouter un [Résolu]
Unbaraki a écrit :

Évidemment ça marche mais du coup je me pose deux questions :
- a quoi sert le javascript dans l'histoire (corriger un bug d'ie peut-être Smiley ohwell ?) ?
- est-ce qu'il n'y a pas un problème d'accessibilité en utilisant simplement le css ?

Voilà... j'attends vos réponses pour rajouter un [Résolu]


Alors aucune idée pour le bug d'IE
Pour l'accessibilité pas du tout il vaut mieux tout afficher puis masquer les éléments avec javascript. Smiley cligne Pour que quelque soit la situation ton menu s'affiche ^^.
Comme l'a souligné N-J, méthode à proscrire.
Aussi, ton script réparé:
function navOver() {
    //Add background color and image on hovered list item
    $(this).css({ 'background' : '#1376c9 url(topnav_active.gif) repeat-x'});
    //Show the subnav
    $(this).find("span").show();
}

function navOut() {
    //Ditch the background
    $(this).css({ 'background' : 'none'});
    //Hide the subnav
    $(this).find("span").hide();
}
            
$(document).ready(function() {
	$("ul#topnav li").hover(navOver, navOut);
    navOver.apply($("#topnav span.open_at_load").parent());
});
Une autre chose qui me dérange un peu, c'est l'utilisation de css au sein du code JS. Pour mieux séparer présentation et comportement, le mieux est l'utilisation de classe (comme pour open_at_load). Genre $(this).add/removeClass("nav_over")
Merci beaucoup. Ça fonctionne très bien par contre je ne comprends pas bien la fin du code :

$(document).ready(function() { 
    navOver.apply($("#topnav span.open_at_load").parent()); 
});
apply (tout comme call) est une méthode héritée du prototype de Function et permet de changer le contexte de cette dernière lors de l'appel. Le contexte est l'objet représenté par le mot-clé this.
myFunction() // contexte implicite, this = window car pas d'identificateur
myFunction.call(null) // contexte explicite, this = window car le contexte est null
myFunction.call(window) // contexte explicite, this = window
myFunction.apply(myObject) // contexte explicite, this = myObject
La différence entre call et apply est dans la façon de passer des arguments. Manière classique pour la première alors que la seconde requiert un objet de la classe Array
function myFunction(arg1, arg2) {}

// this = myObject, arg1 = "foo", arg2 = "bar"
myFunction.call(myObject, "foo", "bar");

// this = myObject, arg1 = "foo", arg2 = "bar"
myFunction.apply(myObject, ["foo", "bar"])  
Voila voila.
Merci pour ces explications.
J'ai modifié légèrement le code pour que le menu reste affiché tout le temps et surtout pour qu'il s'ouvre quand le lien est a.active est non plus en fonction du span.open_at_load.
problème : ça ne marche plus... le sous-menu reste ouverte tout le temps si bien qu'il devient impossible d'ouvrir les autres au survole e la souris ! Je pense que le problème vient de la fonction navOver.apply($("ul#topnav li span a.active").parents("li"));


	 function navOver() { 
    //Add background color and image on hovered list item 
    $(this).css({ 'background' : '#1376c9 url(http://localhost/drupal/sites/all/themes/zen/zen_classic/images/background-menu-active.png) repeat-x'}); 
    //Show the subnav 
    $(this).find("span").show(); 
} 
 
function navOut() { 
    //Ditch the background 
    $(this).css({ 'background' : 'none'}); 
    //Hide the subnav 
    $(this).find("span").hide(); 
	navOver.apply($("ul#topnav li span a.active").parents("li"));  
} 
             
$(document).ready(function() { 
    $("ul#topnav li").hover(navOver, navOut); 
    navOver.apply($("ul#topnav li span a.active").parents("li"));  


<ul id="topnav">

    <li>

        <a href="#">Link</a>

        <span>

            <a href="#" class="active">Subnav Link</a> |

            <a href="#">Subnav Link</a> |

        </span>

    </li>

    <li>

        <a href="#">Link</a>

    </li>

</ul>


Edit : pourquoi sur le forum mon code n'est pas mis en forme avec les couleurs comme le fait si bien alsacreation ?
Modifié par Unbaraki (16 Aug 2009 - 09:21)