1

I have the following template:

<template>
    <div v-if='isLoaded'>
        <div @click='selectSight(index)' v-for='(sight, index) in sights'>
            <img :src="'https://maps.googleapis.com/maps/api/place/photo?maxwidth=300&photoreference=' + sight.photos[0].photo_reference + '&key='">
        </div>
    </div>
</template>

I am wondering is it possible to somehow detect when all images have loaded so I could set isLoaded to true when that happens? I want to avoid displaying the entire div until everything is loaded so I could avoid the flickering of the loading images ( some of them load faster, some of them slower ).

<script>
    export default {
            data(){
                return {
                    sights: null,
                    isLoaded: false
                }
            },
            mounted() {
                axios.get('/getSights/' + this.lat + '/' + this.lng + '/' + this.type + '/' + this.range)
                .then(response => {
                    this.sights = response.data.result.results
                    this.nextPageToken = response.data.result.next_page_token
                }).catch((error) => console.log(error));
            }
    }
</script>

I tried:

var images = document.getElementsByClassName('sight-photos');
images.onload = function () {
    console.log('hey')
}

However I don't see the console message when I tried:

var images = document.getElementsByClassName('sight-photos')[0];
images.onload = function () {
    console.log('hey')
}

I do see the message so I assume you can't use onload on collection of images?

Onyx
  • 5,186
  • 8
  • 39
  • 86

1 Answers1

1

If you use the v-if directive the element is never created & the image will not load. You could however use a v-show directive on the div which would create the html, but keep it hidden. One way here would be to use an array to keep track of all loaded images, which would then be used to update the isLoaded property.

<template>
<div v-show='isLoaded'>
    <div @click='selectSight(index)' v-for='(sight, index) in sights'>
        <img 
          :src="'https://maps.googleapis.com/maps/api/place/photo?maxwidth=300&photoreference=' + sight.photos[0].photo_reference + '&key='"  
          v-on:load="setLoaded(index)"
         >
    </div>
</div>

<script>
export default {
        data(){
            return {
                sights: null,
                loadedSights: []
                isLoaded: false
            }
        },
        mounted() {
            axios.get('/getSights/' + this.lat + '/' + this.lng + '/' + this.type + '/' + this.range)
            .then(response => {
                this.sights = response.data.result.results
                this.nextPageToken = response.data.result.next_page_token
                this.loadedSights = this.sights.map(function(){ return false; });
            }).catch((error) => console.log(error));
        },
        methods: {
            setLoaded: function(index){
                this.loadedSights[index] = true;

                for (var i=0; i< this.loadedSights.length; i++){
                    if (!this.loadedSights[i]){ 
                        this.isLoaded = false;
                        return  
                    }
                }
                this.isLoaded = true;
            }
        }
}
</script>
Stephen S
  • 3,936
  • 2
  • 23
  • 33