简体   繁体   中英

Execute code after rendering all images in vuejs

I want to do some code execution after all images are loaded (need the set scroll in a specific position). I use nextTik() but Codes are processed before loading images . We also can't use mounted and created and methods like this because codes should be executed after clicking on a button. is there any method or trick? thanks

You can use the load event on each image to check if all images have been loaded.

example: https://jsfiddle.net/jacobgoh101/e5bd86k6/1/

<div id="app">
  <img @load="handleLoad"  @error="handleLoad" v-for="i in 10" :src="`https://picsum.photos/${Math.random()*300}/700/?random`"/>
</div>

Javascript

new Vue({
  el: "#app",
  data: {
    imgLoaded: 0
  },
  methods: {
    handleLoad: function(todo){
        this.imgLoaded++;
      if(this.imgLoaded === 10) {
        alert('all image loaded')   
      }
    }
  }
})

Here is my approach for a component having both "static" images and an an arbitray number of images fetched from database :

  • Append two items to the component data: 'imgsLength' and 'loadedImgsLength'
  • Append a 'load' event handler to every img element, that increments 'loadedImgsLength'
  • After all fetched data are loaded, set 'imgsLength' to the number of all img elements

So, you know that all images are loaded when 'loadedImgsLength' > 0 and 'loadedImgsLength' == 'imgsLength'

In this exemple, my component won't be visible until all images are loaded:

<template>
   <div v-show="ready" ref="myComponent">
      ...
      <img src="..." @load="loadedImgsLength++" />  (static image)
      ...
      <img v-for="img in fetchedImg" @load="loadedImgsLength++" />  (dynamic images)
   </div>
</template>

<script>
...
   data(){
      return {
         ...,
         imgsLength : 0,
         loadedImgsLength: 0,
         ...,
      }
   },

   computed: {
     ready(){
        return (this.loadedImgsLength > 0 && this.loadedImgsLength == this.imgsLength)
      }
   },

   async created(){
      ... fetch all data
      this.$nextTick(() => this.$nextTick(this.imgsLength = this.$refs.myComponent.getElementsByTagName("img").length))
   }

         

Based on ( https://stackoverflow.com/a/50481269 enter link description here ) answer I did something like this:

    <img class="card-img-top" :src=" 'images/' + (data.src || 'image-default.png') " 
    :alt="data.alt" @load="handleImagesLoad" @error="handleImagesLoad">

(@load and @error on each image on my page) and

   handleImagesLoad: function($event){
       var images = $('img:not([loaded])');
       var target = $($event.target);
       $(target).attr('loaded', true);

       if(images.length <= 1){
           $('#preloader').fadeOut();
       }
   },  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM