11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Est-il possible de connaître a posteriori le numéro attribué à un item lors d'une recherche par querySelectorAll ?

Par exemple, si
titres = querySelectorAll('h2, h3, h4');

savoir que tel titre particulier correspond à l'item n° i de titres ?

Merci d'avance de votre aide
Modifié par Beka (11 Oct 2018 - 23:15)
Il y a bien une solution simple qui consiste à accoler au titre un span non affiché contenant le numéro du titre.

Mais y a-t-il une instruction en JavaScript permettant de récupérer le numéro d'un item préalablement sélectionné par querySelectorAll ?
Salut

Récupération de toutes les informations disponibles, exemple :

<h1>Forum JS</h1>
<h2>Un beau jour 1</h2>
<h3>Un beau jour 1</h3>
<h4>Un beau jour 1</h4>
<h5 class="beau joli">Un beau jour 1</h5>
<h6>Un beau jour 1</h6>
<h2>Un beau jour 2</h2>
<h3>Un beau jour 2</h3>
<h4>Un beau jour 2</h4>
<h5>Un beau jour 2</h5>
<h6>Un beau jour 2</h6>
<h2 data-test="valeur 1" data-autre="valeur 2">Un beau jour 3</h2>
<h3>Un beau jour 3</h3>
<h4>Un beau jour 3</h4>
<h5>Un beau jour 3</h5>
<h6>Un beau jour 3</h6>


const elemsTitre = document.querySelectorAll('h2, h3, h4, h5, h6');

let elemTitre4 = elemsTitre[4];

console.log(`tagName = ${ elemTitre4.tagName } `); // tagName = H5
console.log(`h numero = ${ elemTitre4.tagName.slice(1) }`); // h numero = 5
console.log(`textContent = ${ elemTitre4.textContent } `); // textContent = Un beau jour 1 
console.log(`classList = ${ elemTitre4.classList } `); // classList = beau joli

let
    elemTitre11 = elemsTitre[11],
    datasTitre11 = elemTitre11.dataset;

console.log(`dataset = ${ datasTitre11 } `); // dataset = [object DOMStringMap]


for (const key in datasTitre11) {
    console.log(`dataset.${ key } = ${ datasTitre11[key] }`);
}

/*
dataset.test = valeur 1
dataset.autre = valeur 2
*/

Modifié par danielhagnoul (12 Oct 2018 - 10:13)
Modérateur
il y a plus court....


<h1>Forum JS</h1>
    <h2>Un beau jour 1</h2>
    <h3>Un beau jour 1</h3>
    <h4>Un beau jour 1</h4>
    <h5 class="beau joli">Un beau jour 1</h5>
    <h6>Un beau jour 1</h6>
    <h2>Un beau jour 2</h2>
    <h3>Un beau jour 2</h3>
    <h4>Un beau jour 2</h4>
    <h5>Un beau jour 2</h5>
    <h6>Un beau jour 2</h6>
    <h2 data-test="valeur 1" data-autre="valeur 2">Un beau jour 3</h2>
    <h3>Un beau jour 3</h3>
    <h4>Un beau jour 3</h4>
    <h5>Un beau jour 3</h5>
    <h6>Un beau jour 3</h6>
    <div id="resultat"></div>
    <script>
        window.addEventListener('DOMContentLoaded', ()=>{
            let output = "";
            document.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach(($el, i) =>{
                output += `<p>index : ${ i + 1 } - item : ${ $el.nodeName.substr(1) }</p>`;
            });

            document.getElementById('resultat').insertAdjacentHTML('beforeend', output);
        });
    </script>
Merci Daniel de tes indications qui m'ouvrent certaines connaissances que je n'avais pas.

Cependant, je crois que je n'ai pas été suffisamment clair dans la formulation de mon message : ce dont j'ai besoin, c'est de pouvoir connaître le numéro qui a été attribué par querySelectorAll à un titre particulier.

Par exemple, si j'associe à un titre un bouton contenant l'appel unefonction(this), j'accède facilement au nœud du titre.
J'ai alors besoin de connaître le numéro attribué à ce titre afin d'accéder aux informations correspondantes que j'ai stockées dans un tableau ayant pour premier indice le numéro des titre.

Il s'agit donc de la démarche inverse de celle de tes exemples : il ne s'agit pas de connaître les informations correspondant à un numéro mais bien de connaître le numéro d'un titre particulier. (Pour reprendre ton premier exemple, savoir que le titre h5 'Un bon jour 1' correspond au numéro 4 de la liste.)

C'est pour cela que j'écris qu'une solution toute simple est d'accoler au titre un span non affiché contenant le numéro du titre.
Mais je voulais savoir s'il existe une instruction Javascript permettant de connaître directement le numéro.
Apparemment, il n'y a pas pour un élément l'équivalent de indexOf pour un item d'une table.

La solution toute simple est donc d'enregistrer avec chaque titre le numéro qui lui a été attribué :

titres = querySelectorAll('h2, h3, h4');
for (i=0; i < titres.length; i++) {
    span_no_de_titre = document.createElement('span');
    titres[i].appendChild(span_no_de_titre);
    span_no_de_titre.innerHTML = i;
    span_no_de_titre.setAttribute('style', 'display: none');
}


Merci de votre participation ! Smiley smile
Modifié par Beka (12 Oct 2018 - 13:44)
Je mettrais plutôt:

titres = querySelectorAll('h2, h3, h4');
for (i=0; i < titres.length; i++)  titres[i].setAttribute('data-num', i);

on récupère ensuite le numéro par
element.getAttribute('data-num');

Non seulement c'est plus court, mais ça évite de regénérer la page pour rien.
Modifié par PapyJP (12 Oct 2018 - 15:27)
Meilleure solution
Oh que merci, PapyJP !

J'ignorais les attributs data-quelque chose.

Cette possibilité va sensiblement me faciliter le travail !

Merciiii !!!
Beka a écrit :
Par contre, je n'ai pas compris « ça évite de regénérer la page pour rien » Smiley decu

Lorsque l'on ajoute des éléments dans le document, le navigateur effectue le plus souvent, sinon systématiquement, une regénération du document pour faire apparaître les nouveaux éléments. Cela doit sans doute dépendre des navigateurs, mais je doute que le fait qu'un élément soit en display:none suffise à éviter cette regénération.
Il ne faut pas non plus trop se préoccuper du temps que cette regénération met à se faire, c'est le plus souvent très rapide et invisible de l'utilisateur.
Les attributs "data-quelquechose" sont une facilité très utile en JavaScript.
On pourrait bien sûr mettre simplement "num" car ce n'est pas un attribut reconnu par les navigateurs, et il ne serait donc pas interprété, mais qui sait si dans 5 ans il ne va pas apparaître un attribut "officiel" portant ce nom. En mettant "data-quelquechose", on est sûr que c'est bien celui qu'on a mis en tant qu'utilisateur.
Modifié par PapyJP (12 Oct 2018 - 16:39)
PapyJP a écrit :
Je mettrais plutôt:

titres = querySelectorAll('h2, h3, h4');
for (i=0; i &lt; titres.length; i++)  titres[i].setAttribute('data-num', i);

on récupère ensuite le numéro par
element.getAttribute('data-num');

Non seulement c'est plus court, mais ça évite de regénérer la page pour rien.


Petit piège dont je me suis aperçu hier après une bonne heure de points d'interrogation ( « Mais p.... !, pourquoi ça ne marche pas ???!!! » ) :

Le i de setAttribute('data-num', i) est converti en chaîne de caractères.
Donc, lorsqu'on veut, par exemple dans une boucle for, comparer le i de comptage avec le i du titre, il faut convertir le i de comptage en chaîne Smiley smile :
i.toString()
Plus précisément, il me fallait déterminer si le numéro de titre était contenu dans une table de numéros de titres générée en utilisant element.getAttribute('data-num').

L'écriture exacte est donc

if (Table_de_titres.indexOf(i.toString()) != -1)  {     /* Le n° i est contenu dans la table */
	Traitement 1
}
else {    /* Le n° i n'est pas dans la table */
        Traitement 2
}