11480 sujets

JavaScript, DOM et API Web HTML5

Salut

Soit 2 <div> en mode table avec des ordonnancements légèrement différents :
https://codepen.io/kerlutinoec/pen/jOBQQad
<div style="position: relative; overflow-x: hidden; margin: 0 0 15vw 0;">
	<div class="figs">
	<figure>
	<img	src="image1.jpg" alt="" height="350" width="350"
			class="maxheight">
	</figure>
	<figure style="vertical-align: bottom; border-spacing: 0;">
	<p class="textesurimage textesurimageD">
	Le premier texte
	</p>
	<img	src="image2.jpg" alt="" height="125" width="350">
	</figure>
	</div>
</div>

<div style="position: relative; overflow-x: hidden; margin: 0 0 15vw 0;">
	<img	src="image3.jpg" alt="" height="250" width="500"
			style="width: 100%;" class="maxheight">
	<div class="figs">
	<figure>
	<img	src="image4.jpg" alt="" height="205" width="305"
			style="vertical-align: bottom;">
	</figure>
	<figure style="vertical-align: middle; background-color: #758C92;">
	<p class="textesurimage textesurimageD">
	Le deuxième texte
	</p>
	</figure>
	</div>
</div>


Le CSS :
.figs { display: table; border-spacing: .2vw 0; }
figure { position: relative; display: table-cell; }
figure img { width: 49.7vw; }

.maxheight { height: auto; max-height: 100vh; object-fit: cover; }
.textesurimage { 
	transform: translateX(-100%); 
	overflow: hidden; 
	width: 50%; 
	bottom: 0; 
	left: 5vw; 
	text-align: left; 
	font-size: 2.5em; 
	text-shadow: 1px 1px 1px #000; 
	}
.textesurimageD { 
	transform: translateX(100%); 
	width: 100%; 
	text-align: center; 
	}
	@media screen and (max-width:1200px) { .textesurimage{font-size: 1.75em;line-height: 1.125em;} }
.animtext { transform: translateX(0); transition: transform 1s ease; }


L'apparition du texte est géré par Intersection Observer :
const callback = (entries, observer) => { entries.forEach((entry) => {
    if (entry.isIntersecting) { entry.target.classList.add("animtext") } } ) };
const options = { root: null, rootMargin: '0px', threshold: 0 };
const myObserver = new IntersectionObserver(callback, options);
const txtList = document.querySelectorAll(".textesurimage");
txtList.forEach(txt => { myObserver.observe(txt); });



Pourquoi le deuxième texte veut bien s'animer mais pas le premier ???

PS : le plus étrange c'est que sur mac ça marche (Firefox, Chrome, Safari) et pas sur PC (ni Firefox, ni Chrome)

PS2 : seule la présence de 'image2' créé le problème (sous windows) ; sans elle ça marche !
Modifié par kerlutinoec (14 Jun 2021 - 16:18)
Modérateur
Et l'eau kerlutinoec,

Quand j'ai appris l'existence de cet objet, j'ai été très enthousiasmé. Et puis j'ai vite déchanté. Le projet sur lequel j'ai la responsabilité actuellement, j'ai des observers un peu partout. Ces derniers sont codés à la main et je n'utilise pas d'intersectionObserver. Coder un observer, c'est très simple :
- 2 objets (subject/observer)
- 4 méthodes (add/rm/notify/update)
- gestion d'une collection (observers)
- implémentation d'une closure (callback)

J'ai eu trop d'ennuis avec (quand tu dois livrer un projet avec des délais courts et que cet objet t'amène son lot de bugs, tu perds vite patience). Non merci, pour la perte de temps.... De toutes manières, cet objet est encore en phase expérimentale. Donc, tu risques la pléthore de bugs.
Modifié par niuxe (15 Jun 2021 - 11:11)
Je suis débutant notamment en JavaScript et, même si je commence à comprendre ce que je fais, la plupart du temps je copie colle du code venu d'ailleurs.
Je m'étais intéressé à IntersectionObserver car j'avais lu qu'il ne grevait pas les performances des pages web.
Qu'en est il de ta méthode ?
Aurais tu un exemple de code ?
Bonjour,

voici ce que j'ai mis en place sur un site pour faire apparaître ou disparaître au scroll du texte enfermé dans une div, avec une transition douce dans l'opacité. On peut aussi choisir de le déplacer, comme tu fais sur l'exemple. Par rapport à ce que je donne plus bas et ton but, tu vas devoir fortement adapter, mais c'est aussi l'intérêt de ce forum, donner des pistes.

Le gros avantage du JavaScript que j'utilise, c'est que si on monte et on descend sur la page, la div disparaît et apparaît de nouveau chaque fois. Alors que sur de très nombreux sites, et l'exemple que tu donnes, l'effet ne se produit qu'une fois, jusqu'au rechargement de la page. C'est assez frustrant.
Une partie de mon code (trouvé sur le net et adapté à mon projet) :
<div class="text-box">

.text-box {
  	tout ce qu'il faut, couleurs, marges, etc.
  	....
     	opacity:.2;
    	transition:opacity 1.4s ease-in-out;}

.text-box.scrolled {
	opacity:.85;}

<script>
	function showIt() {
  const toBeShown = document.querySelectorAll(".text-box"); 
  const halfScreen = window.innerHeight / 1.8;
  toBeShown.forEach((item, i) => {
    const scrolled = (window.scrollY + window.innerHeight);// - (item.offsetHeight/2);

    if (item.offsetTop - window.scrollY < halfScreen) {
      item.classList.add('scrolled');
    } else {
      item.classList.remove('scrolled');
    }
  })
}
window.addEventListener('scroll', showIt);
      </script>

Quand aux performances par rapport au scroll, je n'ai pas poussé les tests jusque là, je ne peux pas m'avancer. Google page speed me donne de très bonnes performances de vitesse mais ce test ne permet pas de mesurer l'effet d'un scroll de la page.
Peut être qu'un { passive: true } aiderait aux performances de scroll.
J 'essaierais ta méthode à l'occasion.
Le fait que l'animation n'ai lieu qu'une fois, en fait je préfère.
Pour le moment j'ai pris le parti de ne finalement pas animer ces textes. (A force de les voir ça m'agaçait Smiley lol )