11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

La structure de titres de mon modèle de documents (plusieurs centaines prévues) est la suivante (par exemple pour h2, la structure étant identique pour h3 ou h4)

<h2>Libellé du titre 1</h2>
<div><button>Bouton 1</button><button>Bouton 2</button></div>
<section>
      <p>Texte correspondant au titre 1</p>
</section>

<h2>Libellé du titre 2</h2>
<div><button>Bouton 1</button><button>Bouton 2</button></div>
<section>
      <p>Texte correspondant au titre 2</p>
</section>

(Les boutons servent à développer et réduire le texte inclus dans la section.)

La feuille de style de base est :

h2 {
     display: inline-block;
     min-width: 20px;
}

h2 + div {
    display: inline-block;
    min-width: 20px;
}

section {
     display: none;
}


Lorsque je mets la section en display: block, j'ai bien
[ Libellé du titre 1 ] [ Boutons ]
[ Texte correspondant au titre 1 ]
[ Libellé du titre 2 ] [ Boutons ]
[ Texte correspondant au titre 2 ]

Mais lorsque la section est en display: none, j'obtiens
[ Libellé du titre 1 ] [ Boutons ] [ Libellé du titre 2 ] [ Boutons ]

Comment faire pour obtenir
[ Libellé du titre 1 ] [ Boutons ]
[ Libellé du titre 2 ] [ Boutons ]

Merci d'avance pour votre précieuse aide.
Modifié par Beka (12 Sep 2018 - 12:17)
Salut,


Hmmm tu pourrais peut être ajouter une <div class="box"> pour contenir
chaque
[ Libellé du titre X ] [ Boutons ]
[ Texte correspondant au titre X ]
Pour justement en faire des blocs.
Comme ici
Attention dans ton css tu as oublié de fermer une accolade.
h2 + div {
    display: inline-block;
    min-width: 20px;

Modifié par JENCAL (12 Sep 2018 - 11:19)
Merci Jencal de la solution que tu proposes, qui me semble tout à fait pertinente.

Comment je fais en JavaScript pour englober le titre, la div des boutons et la section dans une div ?
(Le code initial ne contient que le titre et la section. La div des boutons est ajoutée en js.)

D'autre part, quel est l'intérêt d'attribuer une classe à cette div contenante ?

PS : J'ai ajouté l'accolade fermante.
:)

je vais pas faire un débat sur l'utilisé des classe html. Je vais résumé son utilité en un mot : Ciblé.

Si les divs/bouttons sont ajouté en js, il suffit de complété le code JS pour ajouter le fait d'avoir une div "parente".

Pourrais-tu nous partager ce code JS qui construit les buttons/h2 etc...
Modifié par JENCAL (12 Sep 2018 - 12:41)
« je vais pas faire un débat sur l'utilisé des classe html. Je vais résumé son utilité en un mot : Ciblé. »
Oui, bien sûr, mais le fait qu'il y ait ou non de classe associée à la div ne change pas le bon fonctionnement de ta solution. C'était là le sens de ma question. Smiley smile

Concernant la façon de faire en js, quelles instructions permettent de réunir deux ou trois éléments dans un élément parent ?
Autre façon de poser la question :
Comment en js sélectionner plusieurs éléments frères et placer le tout dans un élément parent ?
Beka a écrit :
« je vais pas faire un débat sur l'utilisé des classe html. Je vais résumé son utilité en un mot : Ciblé. »
Oui, bien sûr, mais le fait qu'il y ait ou non de classe associée à la div ne change pas le bon fonctionnement de ta solution. C'était là le sens de ma question. Smiley smile


Oui tu as raison, mais j'ajoute des classes pour la lecture, même si je ne l'utilise pas ^^


Concernant les functions JS ce sont createElement() et appendChild() mais avant il faudrait voir le JS véritablement dire ce qui est possible ou non.

voila le classique :
var div = document.createElement("div");
var parent = this.parentNode;
parent.insertBefore(div, this);
div.appendChild(this);


Bien entendu cela fonctionne avec un élement de context "this".... le code est à adapter.
Est-ce que, plus simplement, il n'y aurait pas un moyen d'indiquer en css que la section en display: none est de type block ?
Non, car si display:none, y'a plus rien. pas de block, pas de inline block rien. l'elèment n'est physiquement plus la.

surtout qu'un seul display peut être actif
display none
OU
display block... il faut choisir ^^

Par contre tu peux mettre visibility : hidden au lieu de display : none
Modifié par JENCAL (12 Sep 2018 - 15:14)
Merci Jencal
C'est précisément ce à quoi je pensais !
J'essaierai ce soir. (Je suis en train de partir.)
Excuse-moi de te demander pardon :
Si j'ai bien compris, visibility: hidden cache la section mais conserve la place qu'elle aurait dû avoir.
Or une section peut être longue. D'où de grandes plages de blanc ! Smiley decu

Il faut donc garder display: none et utiliser la solution que tu proposais en premier.
Voici donc le code js :

titres = document.querySelectorAll('h2, h3, h4');

for (i=0; i < titres.length; i++) {
     section = titres[i].nextElementSibling;

     div_apres_titre = document.createElement('div');
     titres[i].parentElement.insertBefore(div_apres_titre, section);

     /* Remplissage de la div après le titre avec les boutons (sans intérêt par rapport au sujet) */

    div_parente = document.createElement('div');
    noeud_parent = titres[i].parentNode;
    noeud_parent.insertBefore(div_parente, titres[i]);
    div_parente.appendChild(titres[i]);
    div_parente.appendChild(div_apres_titre);
    div_parente.appendChild(section);

}

Et ça marche !! Smiley biggrin

Merciiii Jencal !!
JENCAL a écrit :
Non, car si display:none, y'a plus rien. pas de block, pas de inline block rien. l'elèment n'est physiquement plus la.


Bon, maintenant que ça marche (merci encore Jencal !), j'aimerais comprendre pourquoi ça marche !
Pourquoi la section, qui physiquement n'existe pas du fait de display:none, existe quand même sans exister lorsqu'elle est incluse dans une div ?? Smiley rolleyes
Administrateur
Bonjour,

Un élément HMTL stylé en CSS avec display: none; "existe" toujours : il est présent dans le DOM et c'est pour cela que tu peux écrire un script JS qui manipule cet élément (DOM : la représentation interne au navigateur du code HTML tenue à jour quand un script le modifie) .
S'il est le premier enfant de son parent, il sera ciblé par le sélecteur CSS :first-child (idem pour toutes les variantes :nth(-last-of)-(child|type) et pour cibler le suivant "ton_élément + ul" cible ul).
En revanche il ne participe visuellement plus au layout et n'est plus "exposé" par l'API accessibilité du navigateur au système d'exploitation (un lecteur d'écran ou tout autre aide technique n'aura aucune chance de lire/percevoir cet élément puisque le navigateur l'ignore donc l'OS donc le lecteur d'écran, ce qui en général est souhaitable car voulu : si c'est pas là visuellement, ce ne doit pas être là dans un lecteur d'écran)

EDIT : avec visibility: hidden; il participe a minima au layout de la page en ayant sa "place réservée" càd ayant la largeur et hauteur qu'il aurait sans cette déclaration mais sans aucun pixel de dessiné ("transparent" mais bien au-delà d'un color: transparent; background: none; pointer-events: none; opacity: 0;). C'est le 2e cas où en plus de ne pas être affiché il n'est pas "exposé" par l'API d'accessibilité du navigateur.
On utilise bien plus rarement cette déclaration que display: none; d'autant plus qu'opacity: 0; fait un peu pareil et est animable/transitionnable (souvent mal fait d'un point de vue accessibilité mais c'est une autre longue histoire)
Modifié par Felipe (13 Sep 2018 - 09:47)
Merci grandement de ces explications détaillées Felipe, mais je ne comprends toujours pas, excuse-moi, pourquoi la div englobant le titre, la div des boutons et la section de texte permet de placer les titres l'un en-dessous de l'autre et non côte à côte.

En d'autres termes, en quoi cette div donne une certaine existence de bloc à la section paramétrée en display: none ?
la div elle est en display block, c'est le contenaire. Son enfant à un display none mais dans un div bloc. Les éléments ne vont pas remonter comme avant car il y cette "limite" via la div bloc.
Meilleure solution
Merci Jencal de la solution que tu proposes, qui me semble tout à fait pertinente.

Comment je fais en JavaScript pour englober le titre, la div des boutons et la section dans une div ?
(Le code initial ne contient que le titre et la section. La div des boutons est ajoutée en js.)

D'autre part, quel est l'intérêt d'attribuer une classe à cette div contenante ?
Modifié par Raphael (20 Sep 2018 - 12:31)