11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Je cherche à obtenir l’élément suivant un élément cible (un media en cours de lecture), ceci afin de switcher vers cet élément par la suite. Sauf qu'il n'est pas forcément un élément frère dans le code, il peut se trouver à un niveau d'imbrication HTML différent, je ne peux donc pas utiliser nextElementSibling :
<main>
  <div class="media-relationship">
    <div class="media">1</div>
    <div>
      <div class="media">Prev</div>
      <div class="media" id="here">Coucou dans la console !</div>
    </div>
    <div class="media">Next</div>
    <div class="media">5</div>
    <div class="media">6</div>
  </div>
  <div class="media">7</div>
  <div class="media">8</div>
</main>

Pour récupérer tous mes media en relation je fais ceci (ce qui pour le HTML de démonstration me sortira les médias 1 à 6 dans un array) :

const media = document.querySelector('#here')
const mediaRelationship = media.closest('.media-relationship')
const relatedMedias = mediaRelationship.querySelectorAll('.media')

Ensuite je ne sais pas comment m'y prendre. J'ai déjà l'élément en cours, mais comment passer à l'élément suivant du tableau ? Avec .find() peut-être ? Mais selon quels critères ?
Je bloque Smiley program
Si quelqu'un a une solution, ou tout au moins une piste à me donner...
Modifié par Olivier C (02 May 2023 - 01:23)
Modérateur
Bonjour,

On peut faire une boucle sur le tableau, rechercher l'indice k où se trouve l'élément media et retourner l'élément ayant l'indice k+1. Par exemple :
const media = document.querySelector('#here');
const mediaRelationship = media.closest('.media-relationship');
const relatedMedias = mediaRelationship.querySelectorAll('.media');
let nextMedia = null;
for(let k=0; k<(relatedMedias.length-1); k++)
	if(relatedMedias[k] == media) nextMedia = relatedMedias[k+1];
console.log(nextMedia.innerHTML);

Amicalement,
Salut,

tu peux aussi transformer ta liste de noeud en array (via ...) pour trouver la position de l’élément avec indexOf puis trouver l’élément suivant avec un +1 :

console.log(relatedMedias[[...relatedMedias].indexOf(media)+1]);

Edit :
En me demandant pourquoi il n'y a pas la fonction indexOf sur la NodeList, je suis tombé sur une solution qui permet de l'y ajouter facilement (et au final ça me semble plus propre que de convertir de NodeList a Array) :
NodeList.prototype.indexOf = Array.prototype.indexOf;
console.log(relatedMedias[relatedMedias.indexOf(media)+1]); 

Modifié par Mathieuu (02 May 2023 - 10:48)
Meilleure solution
Super, merci à vous deux ! J'avais compris qu'une solution pouvait se trouver du côté de .indexOf() mais je ne l'implémentais pas correctement, mes premiers tests avec son utilisation avaient échoué et je n'avais pas eu le temps de réviser mon code hier (ni de vous répondre, mais j'ai vu passer vos messages).

NodeList.prototype.indexOf = Array.prototype.indexOf;

Intéressant, mais n'est-ce pas au final une manière détournée de convertir la NodeList en Array ?
Modifié par Olivier C (03 May 2023 - 05:50)
Je pense/suppose qu'en mémoire cela rajoute juste une méthode à NodeList alors que le passage par ... doit occuper une nouvelle zone mémoire pour y mettre l'array (et du coup si c'est une grande NodeList je suppose que ça peut finir par être coûteux en mémoire), mais je ne sais pas comment le vérifier Smiley ohwell
Merci beaucoup en tout cas. J'aurais une autre question avec un problème dans mon code plus en amont, puis une autre encore, avec un problème plus en aval. Mais ce sera le sujet d'autres topiques.

Je voulais rajouter une fonctionnalité sur mon player qui me semblait simple, mais au final je galère pas mal quand même...
Et bien au final j'ai réussis à régler tous mes problèmes pour cette fonction, je n'aurais donc pas besoin d'ouvrir de nouveaux topics pour celle-ci :
const nextMediaActive = (media, mediaRelationship) => {
  const relatedMedias = mediaRelationship.querySelectorAll('.media')
  const nextMedia = relatedMedias[[...relatedMedias].indexOf(media) + 1] || relatedMedias[0]

  media = nextMedia
  //media.currentTime = 0

  const player = media.nextElementSibling,
        playPauseButton = player.querySelector('.media-play-pause'),
        output = player.querySelector('.media-current-time'),
        progressBar = player.querySelector('.media-progress-bar')
        
  togglePlayPause(media)
  buttonState(!media.paused, playPauseButton)
  currentTime(media, output, progressBar)
}

Je sais, c'est un peu ridicule de se répondre à soi-même, mais on va dire que le forum me sert de journal de bord. A distance je suis content de pouvoir revenir sur un sujet de temps à autre...