28111 sujets

CSS et mise en forme, CSS3

Salut à tous,

Pour faire suite à mon précédent message, je continue la création de ma galerie.

J'ai un nouveau problème et je n'arrive pas à trouver de solution depuis plusieurs jours.

La page contient pleins de vignettes chargées en Lazy Loading, on peut cliquer sur la vignette afin d'avoir la photo en pleine page dans une DIV. Tout ceci fonctionne parfaitement.

Si je surveille le téléchargement de la page, toutes les photos qui devrait se charger lors du clic car j'ai mis un Lazy Loading sur ces images (que je n'ai pas mis ci-dessous d'ailleurs) en pleine page sont téléchargées lors de l'affichage initial de la page, à cause des DIVs qui sont en opacité 0. Je n'avais pas pensé à cela lors du développement. J'ai effectué quelques essais avec du visibility:hidden ou du display:none mais j'ai le même soucis de chargement.

Le but étant que ces photos ne se chargent que lors du clic afin d'alléger la page !

Avez-vous une idée pour solutionner cela ?

Voici juste l'essentiel pour faire les tests :
<!DOCTYPE html>
<html>

<head>
    <meta charset=utf-8>
    <title>Mon test de galerie plein écran</title>
    <link rel=stylesheet href=style.css>
</head>

<body> <a href=#popup-1>Clic pour ouvrir</a> <a href=#close>
        <div id=popup-1>
            <div> <img src=leger.jpg data-src=image.jpg class=lazy> </div>
        </div>
    </a>
    <script src=lazy_img.js></script>
</body>

</html>

[id^=popup-]>div {
    display: flex;
    align-items: center;
    justify-content: center
}

[id^=popup-] {
    z-index: 99999999;
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: rgba(0, 0, 0, .9);
    opacity: 0;
    transition: opacity .4s linear;
    pointer-events: none
}

[id^=popup-]:target {
    opacity: 1;
    pointer-events: auto
}

[id^=popup-]>div {
    height: 100%
}

img {
    max-width: 100%;
    max-height: 100%
}

@keyframes fadeIn {
    0% {
        opacity: 0
    }

    100% {
        opacity: 1
    }
}

/* lazyload.js (c) Lorenzo Giuliani
 * MIT License (http://www.opensource.org/licenses/mit-license.html)
 *
 * expects a list of:  
 * `<img src="blank.gif" data-src="my_image.png" width="600" height="400" class="lazy">`
 */

! function(window) {
    var $q = function(q, res) {
            if (document.querySelectorAll) {
                res = document.querySelectorAll(q);
            } else {
                var d = document,
                    a = d.styleSheets[0] || d.createStyleSheet();
                a.addRule(q, 'f:b');
                for (var l = d.all, b = 0, c = [], f = l.length; b < f; b++)
                    l[b].currentStyle.f && c.push(l[b]);

                a.removeRule(0);
                res = c;
            }
            return res;
        },
        addEventListener = function(evt, fn) {
            window.addEventListener ?
                this.addEventListener(evt, fn, false) :
                (window.attachEvent) ?
                this.attachEvent('on' + evt, fn) :
                this['on' + evt] = fn;
        },
        _has = function(obj, key) {
            return Object.prototype.hasOwnProperty.call(obj, key);
        };

    function loadImage(el, fn) {
        var img = new Image(),
            src = el.getAttribute('data-src');
        img.onload = function() {
            if (!!el.parent)
                el.parent.replaceChild(img, el)
            else
                el.src = src;

            fn ? fn() : null;
        }
        img.src = src;
    }

    function elementInViewport(el) {
        var rect = el.getBoundingClientRect()

        return (
            rect.top >= 0 &&
            rect.left >= 0 &&
            rect.top <= (window.innerHeight || document.documentElement.clientHeight)
        )
    }

    var images = new Array(),
        query = $q('img.lazy'),
        processScroll = function() {
            for (var i = 0; i < images.length; i++) {
                if (elementInViewport(images[i])) {
                    loadImage(images[i], function() {
                        images.splice(i, i);
                    });
                }
            };
        };
    // Array.prototype.slice.call is not callable under our lovely IE8 
    for (var i = 0; i < query.length; i++) {
        images.push(query[i]);
    };

    processScroll();
    addEventListener('scroll', processScroll);

}(this);

Modifié par LeKiffeur (02 May 2020 - 08:36)
Ne trouvant pas de solution et ne voulant pas alourdir les pages, j'ai chercher d'autres solutions...

Voici celle qui me convient le plus, je suis donc parti sur un javascript qui change la source d'une image, ainsi rien n'est téléchargé lors du chargement de la page.

De plus ainsi, la DIV popup n'est écrite qu'une seule fois, c'est encore ça de gagner en chargement.

J'essai aussi de raccourcir le nom des fonctions, je vais continuer de travailler dans ce sens sur l'ID des DIV afin de gagner encore quelques octets mais qui sont répétés des centaines voir des milliers de fois par page !

Je ne mets pas résolu car j'aimerais bien trouvé une solution toute en CSS, si vous avez, je prends, en attendant je continu mon travail avec ça.

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Mon test de galerie plein écran</title>
</head>

<body>
    <h1>Mon test de galerie plein écran</h1>
    <a href=#popup onclick="R('1.jpg');">1</a><br>
    <a href=#popup onclick="R('2.jpg');">2</a><br>
    <a href=#popup onclick="R('3.jpg');">3</a><br>
    <div id="container">
        Blablabla !!
    </div>
    <a href="javascript:history.back()">
        <div id="popup">
            <div>
                <img id=I src=data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7>
            </div>
        </div>
    </a>
</body>

</html>


body {
    height: 100%;
}

#container,
#popup>div {
    display: flex;
    align-items: center;
    justify-content: center;
}

#popup {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: rgba(0, 0, 0, 0.9);
    opacity: 0;
    transition: opacity 400ms linear;
    pointer-events: none;
}

#popup:target {
    opacity: 1;
    pointer-events: auto;
}

#popup>div {
    height: 100%;
}

img {
    max-width: 100%;
    max-height: 100%;
}


function R(a) {
    document.getElementById("I").src = a;
}

Modifié par LeKiffeur (03 May 2020 - 11:44)
Modif, au lieu d'un

<img id="I" src="#">

Je passe en

<img id=I src=data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7>

Afin de créer un GIF de 1×1px transparent.

J'adore les monologues...

Ah aussi, j'ai remplacé

<a href="#close">

Par

<a href="javascript:history.back()">

Dans le but d'éviter d'avoir un historique à force de cliquer, historique qui n'existe pas réellement car à chaque fois l'image est écrasée...
Modifié par LeKiffeur (03 May 2020 - 11:45)
Modérateur
Hello,

Il existe un lazy loading natif, tu peux l'utiliser si ça passe la compatibilité que tu veux avoir…

Sinon, comme tu l'as fait, une autre idée serait d'avoir un seul endroit (<div>) pour voir les images en grand, pour ensuite charger tes grandes images une à une lors du click sur une vignette…
Merci pour ta réponse.

J'avais déjà effectué plusieurs tests avec loading="lazy" dans la balise IMG mais ça ne fonctionnait pas.