vvo / lazyload

:bullettrain_front: Lazyload images, iframes, widgets with a standalone JavaScript lazyloader
https://vvo.github.io/lazyload/
MIT License
938 stars 158 forks source link

Onload attribute method #70

Open nico3333fr opened 9 years ago

nico3333fr commented 9 years ago

Hello,

I'm just wondering if there is a version of the script without setting up onload="lzld(this)" in the HTML code ?

As I'm using CSP and trying to avoid inline js-attributes, would it be possible to set up a version with an data-attribute (for example) instead of onload ?

Thanks a lot for reading, Nicolas

vvo commented 9 years ago

The onload attribute does the trick of adding the image to the list of image to lazyload by using the browser onload attribute on an empty/small image.

Otherwise we would have to rely on document dom ready and it's not faster enough because you have to wait for all scripts/css to load.

One possibility was to add a global onload dynamically on the body and then see if the event would bubble up (using useCapture), and filter based on the dom node.

Could be a very good possibility, reference: https://twitter.com/zeroload/status/386861545256280065

vvo commented 9 years ago

=== Welcoming any improvement if it does make a difference/simplify the integration.

Adding onload with useCapture on body element is interesting, but you first need to have a reference to the body element anywhere (even when included in the )

vvo commented 9 years ago

also see https://github.com/vvo/lazyload/issues/45

jpvincent commented 9 years ago

It's already possible to write something like this :

lzld(document.querySelector('.element'));

That means you can trigger the lazyload detection whenever you want, with the syntax you think is right.

With a small modification of the library that I made, one can even support arrays of DOM nodes :

    function register(elt) {
        // flatten the execution of the register function
        if('length' in elt){
            for (var i = 0; i < elt.length; i++) {
                register(elt[i]);
            }
            return;
        }
vvo commented 9 years ago

@jpvincent would be a great addition to the library.

Also yes you can trigger manually, it may be slower than onload= but can make sense in SPA where you control everything

jpvincent commented 9 years ago

sure, will think about it in my case, it was because we had to add support for lazy-loading background images.

vvo commented 9 years ago

2015-10-11-010800_1396x439_scrot

giphy 2

vvo commented 9 years ago

cc @jpvincent

englishextra commented 8 years ago

I do it without onload attr in HTML mark-up:

/*!
 * replace img src with data-src
 */
evento.add(window, "load", function () {
    var b = document.getElementsByTagName("img") || "";
    if (b) {
        for (var c = 0; c < b.length; c++) {
            var d = b[c].dataset.src || b[c].getAttribute("data-src");
            d && (lzld(b[c]),(b[c].style.display="block"));
        }
    }
});
vvo commented 8 years ago

Nice! Thanks for the feedback.

AndrewCraswell commented 7 years ago

Sorry to revive an old issue, but I was searching how to do exactly what @englishextra had accomplished, but wouldn't this script be a little more performant and simpler?

window.addEventListener('load', function () {
       var imgs = document.querySelectorAll('img[data-src]') || null;
       if (imgs) {
           for (var i = 0; i < imgs.length; i++) {
               lzld(imgs[i]);
           }
       }
});
englishextra commented 7 years ago

@AndrewCraswell This is what I use now.

It appears that the fastest would be to set up a technical CSS class, and then select with getElemenetsByClassName

I try to avoid querySelectorAll, it's much slower.

window.addEventListener('load', function () {
       var imgs = document.getElementsByClassName('data-src-img') || "";
       if (imgs) {
           for (var i = 0; i < imgs.length; i++) {
               lzld(imgs[i]);
           }
       }
});

You will need that class, for instance, to set up CSS transition opacity.