11484 sujets

JavaScript, DOM et API Web HTML5

Bonjour tout le monde !

Je travail actuellement sur le JavaScript (DOM et événements) pour faire un menu déroulant dans le même style que celui de Microsoft (le menu qui se déroule sur toute la largeur de l'écran).

Je coince au niveau de la création de l'événement click/onclick. En effet, je ne comprend pas pourquoi ma div (id : div--sMenu) jouant le rôle du sous menu ne s'affiche pas. Si on clique plusieurs fois et très rapidement sur le bouton 3 +, on peut la voir (sous Firefox) apparaître et disparaitre aussitôt.

J'ai remplacé le code de mon événement par un alert('Tu as cliqué !'); pour tester si mon code marche et en cliquant sur le Bouton 3 +, le navigateur affiche bien « Tu as cliqué ! ».

J'avoue être complétement perdu. D'autant plus la création de la div (id : div--sMenu) seule fonctionne. Après plusieurs recherches, je me permet de vous demander votre aide. Je ne comprend pas ce qui se passe.

J'espère que vous allez pourvoir m'expliquer ce qui ne va pas. J'utilise les dernières versions de MSIE, Firefox et Chrome.

Merci d'avance.

Voici mes codes sources :
HTML 5 :
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="utf-8" />
    <title>Menu bleu</title>
    <link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<body>
    <header class="header">
        <nav id="nav">
            <div id="div--menuPose">
                <a href="index.html" class="a-menuItem">Bouton 1</a>
                <a href="index.html" class="a-menuItem a-menuItemLarge">Bouton 2</a>
                <a href="index.html" class="a-menuItem a-menuItemLarge" id="but_3">Bouton 3 +</a>
                <a href="index.html" class="a-menuItem">Bouton 4</a>
            </div>
        </nav>
    </header>
    
    <!-- Section test -->
    <section>
        <p>Un peu de texte dans une section !</p>    
    </section>
    
    <!-- Code JavaScript -->
    <script type="text/javascript" src="script.js"></script>
</body>
</html>


JavaScript :
// On sélectionne l'élément qui va recevoir l'événement
var event_btn3 = document.getElementById('but_3');

event_btn3.addEventListener('click', function() {
    //alert('Tu as cliqué !');
    
    // Création de la div sous-menu (div--sMenu)
    var div_sMenu = document.createElement('div');
    
    // J'assigne les attributs
    div_sMenu.id = 'div--sMenu';
    
    // On insert div_sMenu
    document.getElementById('nav').appendChild(div_sMenu);
}, false);


CSS :
body {
    margin: 0;
    padding: 0;
    background-color: #f0f0f0;
}
.header {
    margin: 0;
    padding: 0;
    height: 100px;
    font-family: sans-serif;
    font-style: normal;
    font-weight: normal;
    background-color: #262626;
}
#nav {
    position: relative;
    top: 50px;
    left: 0px;
    margin: 0;
    padding: 0;
    height: 50px;
    background-color: #3a90cd;
}
#div--menuPose {
    margin-left: auto;
    margin-right: auto;
    margin-bottom: 0;
    margin-top: 0;
    padding: 0;
    width: 1000px;
    height: 50px;
}
/* --- Animations du menu --- */
.a-menuItem {
    margin: 0;
    padding: 0;
    padding-top: 12px;
    box-sizing: border-box;
    display: inline-block;
    float: left;
    width: 120px;
    height: 50px;
    font-family: sans-serif;
    font-size: 1.2em;
    font-weight: normal;
    font-style: normal;
    text-decoration: none;
    text-align: center;
    color: #f0f0f0;
    background-color: #3a90cd;
}
.a-menuItemLarge {
    width: 160px;
}
.a-menuItem:visited {
    background-color: #3a90cd;
}
.a-menuItem:hover, .a-menuItem:focus {
    background-color: #419ddf;
}
.a-menuItem:active {
    background-color: #2b70a0;
}
section {
    margin: 0;
    padding: 0;
    border-top-style: solid;
    border-top-width: 3px;
    border-top-color: #e1e1e1;
    border-bottom-style: solid;
    border-bottom-width: 3px;
    border-bottom-color: #e1e1e1;
    background-color: #ebebeb;
    height: 500px;
}
/* Styles sous menu (pour l'événement) */
#div--sMenu {
    margin: 0;
    padding: 0;
    /*border: solid 1px blue;*/
    background-color: #2b70a0;
    height: 100px;
}

Modifié par SilverFox (31 Jul 2014 - 21:38)
Bonjour,

Si je place :
- votre code css dans la section head de la page html
- votre code Javascript tout à la fin du fichier html (après "</html>")
si je remplace tous les href="index.html" par href="#"
et si je clique sur "Bouton 3+" (avec Firefox, Google Chrome et Internet Explorer)
j'ai bien une div de couleur bleue qui s'affiche.
Si je clique dix fois, dix éléments div sont ajoutés, ce qui correspond bien à votre script.
Pour que ça fonctionne, il est nécessaire de placer le javascript en fin du fichier html, ou de l'appeler par l'intermédiaire de l'événement onload de l'élément body.

Personnellement, avec ce type de menu, je n'utilise pas cette méthode :
- Dans le code html, j'écris autant de div qu'il y a de sous-menu, avec le style "display:none"
- Je place un onclick='onclique("btx") dans les élément lien (menu principal)
- Dans la fonction onclique(menu1), j'écris
document.getElementById(menu1).style.display = "block"
Ensuite :
- il faut cacher l'ancien menu de niveau 2 (style='none') si on clique plusieurs fois de suite sur un menu différent.
- il faut éventuellement utiliser 'position:absolute', si on souhaite afficher le sous-menu par dessus le texte de la page.

J'ai un exemple qui fonctionne ici :
http://calendar.local-base.com/

Mais si on vous a demandé de travailler sur le DOM et les évènements, je comprends votre façon de faire...
Modifié par jlon (02 Aug 2014 - 15:37)
Merci de votre réponse.

J'ai essayé la solution que vous m'avez proposé. Elle fonctionne mais ce qui me chagrine c'est ce mélange de code HTML, CSS et JavaScript dans le même fichier.

J'apprends à créer des sites web et dans les cours (OpenClassrooms) ils conseillent plutôt de séparer le code HTML, CSS et JavaScript.

L'idée c'est de faire en sorte que lorsqu'on clique sur le « Bouton 3 + », le sous-menu se déroule et le bouton prend la couleur du sous-menu et devient « Bouton 3 - ». Si on clique de nouveau sur ce dernier, le menu disparait et le bouton redevient « Bouton 3 + »,

Ce qui est très étrange c'est qu'en replaçant l'évènement par un alert, le code fonctionne.
Administrateur
Bonjour,

l'idéal est en effet d'avoir un fichier HTML, un fichier CSS (appelé depuis le code HTML avec un élément link) et un fichier JS (appelé via script et attribut src).
Placer l'élément script juste avant la balise fermante </body> est en effet recommandé pour éviter de bloquer le chargement du reste (je la fais simple... simpliste même).

SilverFox a écrit :
Ce qui est très étrange c'est qu'en replaçant l'évènement par un alert, le code fonctionne.

Y a-t-il l'équivalent JavaScript du $(document).ready(function() { /* code */ }); de jQuery ?
Essentiel pour être certain que JS s'exécute après que le DOM soit construit par le navigateur et prêt.
Je trouve http://stackoverflow.com/questions/9899372/pure-javascript-equivalent-to-jquerys-ready-how-to-call-a-function-when-the mais si quelqu'un a un tuto en français, ça m'intéresse (en précisant la compatibilité de chaque fonction... Perso c'est un peu compliqué : tant que je dois assurer IE8+ j'utilise jQuery mais ce sera tellement moins nécessaire quand IE8, IE9 et IE10 passeront à peu près en même temps sous les 1% de parts de marché en France Smiley smile )
Modifié par Felipe (03 Aug 2014 - 17:53)
Bonjour,

Il est effectivement vivement conseillé d'externaliser le javascript et le css dans des fichiers distincts, surtout s'ils sont utiles à plusieurs pages...

Vous pouvez externaliser le javascript, placer le code dans une fonction, et appeler la fonction, soit en faisant appel à la fonction après la balise de fin du html, soit via l'événement onload de l'objet body.