Version imprimable du sujet

Cliquez ici pour voir ce sujet dans son format original

Forums MacBidouille _ Les Langages Du Web _ Utiliser onload sur une div

Écrit par : Anard 9 Mar 2019, 16:15

Bonjour,

Je cherche à executer une action après chargement complet d'une div, comme ça se fait pour la balise body.
Je m'explique : sur http://test.musiquesmagiques.fr/Collection, je propose une galerie photos. Il faut cliquer sur un album pour charger les miniatures des photos qu'il contient par AJAX (par sécurité, un lien direct charge la page complète finale au cas où Javascript serait désactivé).

Au départ, Javascript affiche une icône "chargement" et les miniatures sont grisées. Quand il reçoit la réponse de PHP, les photos réapparaissent normalement et l'icône "chargement" disparait. Mais, en tout cas chez moi avec une connexion digne des années 90, les photos n'apparaissent pas encore, elles restent à charger.
Dans l'idéal, j'aurais aimé que ceci n'intervienne qu'une fois que les photos contenues dans la div sont entièrement chargées.
Malheureusement, l'évènement onload n'est applicable qu'au body ou aux éléments externes (img, iframes, script, style, etc).
J'ai pensé appliquer le script onload sur la dernière image du lot, mais ce n'est pas forcément celle qui sera finie de charger en dernier.

Connaîtriez-vous un moyen de parvenir à mes fins ?

Merci beaucoup pour votre aide.

Écrit par : Philippe64 9 Mar 2019, 17:03

Ton site avances bien !
Tu pourrais mettre tes images avec un un système de lazy loading, du coup tu charges ton contenu via ajax avec juste une image de remplacement pour patienter (un gif par exemple). Une fois que ton ajax est chargé tu demandes le chargement des images (via ton script de lazy loading) qui se fera en douceur avec par exemple un petit effet de fondu.
(par exemple : http://jquery.eisbehr.de/lazy/)

par exemple, quand tu charges un bout de code avec une image, au lieu de faire :
<img src="images/1.jpg" />
tu fais :
<img class="lazy" data-src="images/1.jpg" />

et quand c'est chargé, tu actives le téléchargement des images via le script de lazy loading.


Écrit par : Anard 9 Mar 2019, 19:42

Merci à toi.

Citation
Ton site avances bien !
Heureusement que la graphiste est passée par là wink.gif

Je n'aime pas trop jQuery (enfin surtout je ne connais pas du tout, et j'ai déjà bien du mal à ne pas me perdre entre tous ces "interlocuteurs" imbriqués les uns dans les autres (HTML, CSS, PHP et JS). Dur de garder la tête bien rangée (ça doit d'ailleurs se voir dans mon code wink.gif )
Après, de ce que j'ai compris, jQuery n'est qu'une extension de Javascript. La même chose doit pouvoir être obtenue en JS pur (à moi de chercher wink.gif )
En tout cas merci pour la piste, je ne connaissais déjà pas cet attribut "data-src" qui en effet peut-être bien pratique pour ce genre de choses. Est-ce que le chargement de l'image sur l'ordinateur du client commence dès que je met un fichier valide dans "data-src" ou est-ce que ce n'est que sémantique ?

Je vais continuer à fouiner mais si je comprends bien, je n'ai pas trop d'autre choix que de me fier aux onload des images elles-mêmes.

En fait pour le moment ma technique consiste à charger en Ajax directement l'ensemble de la div "miniatures", ce que je trouve assez simple à mettre en œuvre. J'aimerais quand même rester sur un gif "chargement" unique, mais le principe reste identique.
En réfléchissant très rapidement, je pensais utiliser une variable globale dans mes scripts JS photosRestantes qui prend la valeur du nombre de photos à charger dès la réponse PHP à ma requête Ajax.
Chaque photo disposerait d'un genre de truc comme ça:
Code
onload=function() {
    photosRestantes--;
    this.src = this.data-src; // avec effet de transition magnifique !!!
    this.data-src = "";
    if (!photosRestantes) {
        document.getElementById('chargement').style.visibility = 'hidden';
        document.getElementById('miniatures').style.opacity = '1.0'; // idem avec transistion magnifique :D
    }
}

Mais je me demande si ce n'est pas un peu bourrin biggrin.gif, j'évite d'habitude les variables globales

J'aurais une seconde question tant que je suis ici :
Dans d'autres parties du site, j'utilise le même type de chargement Ajax, mais j'aimerais parfois interdire un clic pendant le chargement.
Y a-t-il une propriété qui puisse faire ça ? J'utilise disabled=true sur les formulaires, mais j'ai l'impression que ça ne fonctionne pas sur le reste de la page...

Écrit par : Anard 10 Mar 2019, 18:16

Bien. J'ai peur de ne pas avoir bien compris du coup... unsure.gif

Le tag "data-src" ne veut en fait rien dire de spécial pour le navigateur d'après ce que j'ai pu lire. Donc les url qui sont à l'intérieur ne sont en fait pas chargées du tout, sauf quand JS fera son travail pour replacer le chemin dans l'attribut "src".
Bien que 99% des utilisateurs aient probablement Javascript d'activé, je considère l'accessibilité comme primordiale et ne veux surtout pas limiter le rendu si JS n'était pas activé. Les scripts ne me servent qu'à apporter des effets et éviter le chargement d'une page complète quand on clique sur un lien qui ne fera que remplacer une "div". Comme je disais chaque fonction javascript est écrite comme ceci :

Code
<a onclick="fonctionJavascript(); return false;" href="lienDirect.php">

Ainsi, si Javascript n'est pas activé (ou s'il y a une erreur dans mon code JS wink.gif), le lien vers la page brute devient actif et l'utilisateur final ne verra pas vraiment la différence.

Du coup, j'ai opté pour cette solution. Sachant que la galerie est constituée comme ceci :
Code
<!-- Liste des albums -->
<div class="albums">
    <div class="photo">Premier album</div>
    [...]
    <div class="photo">Dernier album</div>
</div>
<!-- Miniatures -->
<div class="photos">
    <div class="photo">Première photo</div>
    [...]
    <div class="photo">Dernière photo</div>
</div>




Je trouve l'effet final assez joli, et un navigateur sans script affichera la page normalement sans les effets de transition.
Mais vu que je ne suis pas très au point, si je réinvente trop la roue ou si je me complique trop la tâche, je suis preneur d'astuces wink.gif

Merci beaucoup. http://test.musiquesmagiques.fr/Collection/Galerie.php Euh… pour le contenu, c'est les premières photos que j'ai trouvé sur mon ordi. Cette partie, ce ne sera pas mon taf wink.gif

Écrit par : No6 10 Mar 2019, 23:27

Citation
Je n'aime pas trop jQuery (enfin surtout je ne connais pas du tout, et j'ai déjà bien du mal à ne pas me perdre entre tous ces "interlocuteurs" imbriqués les uns dans les autres (HTML, CSS, PHP et JS). Dur de garder la tête bien rangée (ça doit d'ailleurs se voir dans mon code wink.gif )
Après, de ce que j'ai compris, jQuery n'est qu'une extension de Javascript. La même chose doit pouvoir être obtenue en JS pur (à moi de chercher wink.gif )


la fonction nouvelle, et équivalente en JavaScript c'est le Fetch => https://developer.mozilla.org/fr/docs/Web/API/Fetch_API/Using_Fetch

qui même si elle est indiquée comme expérimentale est maintenant utilisable sur tous les navigateurs => https://caniuse.com/#search=fetch

pour s'asurrer d'une compatibilité absolue il faut ajouter le PolyFill indiqué sur la page MDN.

---

Pour que tu comprenne mieux ton probleme : les commandes Ajax sont asynchrone.
ce qui signifie; pour ce type de fonctions, qu'entre le moment ou elle sont lancées et le moment ou elles ont une réponse (qui généralement prend du temps) l'interpréteur JS n'attend pas les bras croisés que la fonction en ai terminé avant de passer à autre chose, s'il y a du code à faire par la suite, alors il le traite tout de suite et c'est un process à part qui se chargera de faire le traitement demandé lorsque que la réponse arrivera.

Pour gérer les questions de synchronisation autour de différents appels asynchrones, il faut utiliser les mécanismes des promesses, ce que jQuery ne fait pas , car il procède par callBack, qui reste limité (comme le fait le Fetch à la base, mais avec un chainage).
https://developer.mozilla.org/fr/docs/Web/JavaScript/Guide/Utiliser_les_promesses

Propulsé par Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)