11480 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

j'expérimente un petit code dont le but est d'ouvrir le contenu d'une class (du texte et une image) lors du scrool de la souris. La class est dans une div :
<div class="text-box">

Je me suis inspiré de ce code :
https://webdesign.tutsplus.com/tutorials/simple-fade-effect-on-scroll--cms-35166
Je l'ai modifié un peu car mon but est de faire passer le contenu de la class de opacity: .6 à opacity: .9 au scrool et aussi de lui ajouter un background.
Mon code modifié :
<script>
	const checkpoint = 500; 
window.addEventListener("scroll", () => {
  const currentScroll = window.pageYOffset;
  if (currentScroll <= checkpoint) {
    background = "gray" - currentScroll / checkpoint;
  } else {
    background = "linear-gradient(lightblue, gray, yellow, gray, yellow, rgba(200, 30, 255, 1)";
    opacity = 0.9;
  }
  document.querySelector(".text-box").style.background = background;
  document.querySelector(".text-box").style.opacity = opacity;
});
	</script>

Il fonctionne exactement comme je le veux sur la première class mais le problème est que j'en ai quatre du même nom, situées plus loin sur la page, et je voudrai agir de la même façon sur les trois autres class, au scrool. Seule la première reçoit le code JavaScript, les trois autres, non. J'ai lu que l'on pouvait pointer plusieurs éléments avec "document.querySelectorAll" en les séparant par une virgule mais ça ne fonctionne pas, il semble qu'il faille ajouter du code.

Merci pour l'aide.
Bonjour,

Non seulement il faut que le sélecteur soit pertinent (et dans votre cas il ne faut pas prendre .querySelector mais .querySelectorAll) mais il faut aussi itérer le code dans une boucle (ou une .map) afin qu'il ne limite pas à une seule exécution.

Voici comme exemple un code passant un attribut target _blank sur tous les liens d'une page qui ne fait pas partie du même nom de domaine :
const externalLinks = (() => {
  var anchors = document.querySelectorAll('a')
  for (const anchor of anchors) {
    if (anchor.hostname !== window.location.hostname) anchor.setAttribute('target', '_blank')
  }
})()

Modifié par Olivier C (21 Sep 2020 - 08:36)
Merci pour la réponse.
J'avais entendu parler de cette itération de code dans ce cas précis, sans savoir comment le mettre en place.
Serait-il possible d'avoir des précisions, par rapport à mon cas ? Pour le moment, je me contente de la première class, les autres sont en "hover".
J'ai aussi lu, mais c'est une autre question, que l'utilisation de "querySelector" était plus lourde en terme de performances que "getElementById" ou "geteEementByClass".

A plus.
Alors je viens de relire le code et il y a un autre problème : le code ne marche qu'en fonction d'une hauteur définie (hauteur de la fenêtre + 500px). Du coup, même avec intégration dans une boucle il faut aussi régler ce problème. Mais désolé, je n'aurais pas le temps de me pencher sur la réimplémentation de ce code.

Pour le poids des sélecteurs, laissez tomber ce problème qui n'en est pas un, à ce niveau c'est de la micro-optimisation. De toute façon .querySelectorAll() est un sélecteur nouvelle génération performant.
Bonjour,
effectivement, les class seront toutes visées en même temps à 500px (valeur que j'ai modifié par rapport à l'original). L'effet d'ouverture progressive du contenu ne sera visible que sur la première class.
D'accord pour le poids des sélecteurs, les gains de performance ne sont pas à chercher ici.
Je vais laisser comme ça pour le moment, c'est surtout la page d'accueil la plus importante et le code fonctionne bien sur celle-ci.
Il existe beaucoup d'autres codes js pour faire ça, je vais regarder et tester, parce que j'avais aussi l'intention de faire plus. Par exemple, faire revenir le contenu de la class à son état original lorsque la souris remonte le scrool. Peut-être que je demande trop, mais maintenant que ça fonctionne à minima, je peux aller plus loin.

Merci, en tous cas.
Juste une piste : plutôt que de calculer une hauteur de fenêtre + 500px il est possible de trouver la hauteur d'un élément dans la page. Avec par exemple .offsetTop ou quelque chose du genre, je n'ai pas creusé la question.
Bonjour,
c'est à voir. Je suis un peu débutant en js et j'y vais à mon rythme. L'idéal serait : ouverture de chaque class au scroll, quand on s'en approche et fermeture de cette class quand on s'en éloigne. Il va aussi falloir tenir compte des mobiles. J'ai effectué un essai sur mon serveur perso. Sur un mobile, il faut toucher l'écran pour avoir l'effet, c'est le comportement normal.