Показать сообщение отдельно
  #9 (permalink)  
Старый 11.10.2019, 22:15
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

vue lazyLoad
madeas,

<!DOCTYPE html>

<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
    .grid{
            display: flex;
            flex-direction: column;
    }

    picture img{
            width: 300px;
            height: 350px;
            background-color: #FF00FF;
            opacity: 1;
            transition: .8s 2s;
    }
    picture.lazy-initial .img{
            opacity: 0.2;
    }
    </style>
</head>

<body translate="no">

<div id="app">
    <responsive :list="list"></responsive>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script id="rendered-js">
    Vue.component("responsive", {
    props: ["list"],
    template: `
    <div class="grid">
    <template v-for="(f, index) in list" :key="index">
            <picture class="lazy lazy-initial">
                <source :srcset="f.large" media="(min-width: 62em)">
                <source :srcset="f.medium" media="(min-width: 48em)">
                <source :srcset="f.small" media="(min-width: 36em)">
                <img :alt="f.caption" :data-src="f.img" src >
            </picture>
    </template>
    </div>` });


new Vue({
    el: "#app",
    created() {
        this.list = JSON.parse(`
        [
            {
                "large": "190x127",
                "medium": "350x234",
                "small": "520x347",
                "img": "330x220"
            },
            {
                "large": "190x127",
                "medium": "350x234",
                "small": "520x347",
                "img": "330x220"
            },
            {
                "large": "190x127",
                "medium": "350x234",
                "small": "520x347",
                "img": "330x220"
            },
            {
                "large": "190x127",
                "medium": "350x234",
                "small": "520x347",
                "img": "330x220"
            },
            {
                "large": "190x127",
                "medium": "350x234",
                "small": "520x347",
                "img": "330x220"
            }
        ]
        `);
    } });

// Update the image source on elements in the picture element
function loadImage(picture) {

    var sources = picture.children;
    var loadingPath = "https://via.placeholder.com/";

    for(var s=0; s<sources.length; s++) {
        // remove the lazy-initial class when the full image is loaded to unblur
        sources[s].addEventListener('load', image => {
            image.target.closest("picture").classList.remove("lazy-initial")
        }, false);

        // update the src or srcset urls
        if (sources[s].hasAttribute("srcset")) {
          sources[s].setAttribute("srcset",loadingPath + sources[s].getAttribute("srcset"));

        } else {
            sources[s].src = loadingPath + sources[s].dataset.src ;
        }


    }

}

// Stop observing this image and load its source
function lazyLoad(elements) {
    elements.forEach(item => {
        if (item.intersectionRatio > 0) {
            observer.unobserve(item.target);
            loadImage(item.target);
        };
    });
};


// Set up the intersection observer to detect when to define
// and load the real image source
var options = {
    rootMargin: "100px",
    threshold: 1.0
};
var observer = new IntersectionObserver(lazyLoad, options);

// Watch for all pictures with a "lazy" class
var pictures = document.querySelectorAll('picture.lazy');
pictures.forEach(pic => {
    observer.observe(pic);
});






        </script>


</body>
</html>
Ответить с цитированием