最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vuejs 2: how to detect img.complete property - Stack Overflow

programmeradmin6浏览0评论

I have code that fetches a list of images as an object like

[
  { src: '/path/to/img.jpg', loaded: false },
  ...
]

and template that then renders them as HTML like:

<div
  v-for="image in alltheimages"
  :key="image.id" >
  <transition name="fade" appear>
  <img
    :src="image.src"
    v-show="image.loaded"
    @load="image.loaded = true"
    />
  </transition>
</div>

This works well when first loading the page; the images fade in as soon as they're loaded.

However there's a problem when the image is already loaded in cache because then the @load never fires on the new <img> element. In these situations I can check the DOM img tag's plete property, but how can I do that in VueJS?

I've tried v-show="thisplete || image.loaded" but this just points to window. I thought I could use a method call and pass a reference to the element which initiated the call, but I can't find out how to do that either.

I realise I could load all the images separately with new Image(), bind a listenter to the load event before I provide src and from there update the data to say the thing is loaded, but that a whole lotta code and objects - be much nicer to be able to use the DOM elements Vue creates.

I have code that fetches a list of images as an object like

[
  { src: '/path/to/img.jpg', loaded: false },
  ...
]

and template that then renders them as HTML like:

<div
  v-for="image in alltheimages"
  :key="image.id" >
  <transition name="fade" appear>
  <img
    :src="image.src"
    v-show="image.loaded"
    @load="image.loaded = true"
    />
  </transition>
</div>

This works well when first loading the page; the images fade in as soon as they're loaded.

However there's a problem when the image is already loaded in cache because then the @load never fires on the new <img> element. In these situations I can check the DOM img tag's .plete property, but how can I do that in VueJS?

I've tried v-show="this.plete || image.loaded" but this just points to window. I thought I could use a method call and pass a reference to the element which initiated the call, but I can't find out how to do that either.

I realise I could load all the images separately with new Image(), bind a listenter to the load event before I provide src and from there update the data to say the thing is loaded, but that a whole lotta code and objects - be much nicer to be able to use the DOM elements Vue creates.

Share Improve this question asked Dec 26, 2017 at 21:44 artfulrobotartfulrobot 21.4k12 gold badges60 silver badges90 bronze badges 2
  • There's a library for this issue: npmjs./package/vue-images-loaded – ssc-hrep3 Commented Dec 27, 2017 at 0:39
  • May not be what you like, but most of my ponents just have a property 'mounted' which I programmatically set from false to true in the mounted lifecycle hook. That would allow you to do something as v-show="mounted && image.loaded". If you care about too much code, write a mixin for it? – David Heremans Commented Dec 27, 2017 at 7:05
Add a ment  | 

4 Answers 4

Reset to default 7

You can do this with a directive.

<div
  v-for="image in alltheimages"
  :key="image.id" >
  <transition name="fade" appear>
  <img
    :src="image.src"
    v-show="image.loaded"
    v-loadedifplete="image"
    @load="image.loaded = true"
    />
  </transition>
</div>

Then in your app.

new Vue({
  ...
  directives: {
    loadedifplete: function(el, binding) {
       if (el.plete) {
         binding.value.loaded = true;
       }
    }
  }
  ...
});

I didn't have any luck with this method, nor with vue-images-loaded but vue-onload worked like a charm.

In main.js add:

import OnLoad from 'vue-onload'
Vue.use(OnLoad);

and on the images you are loading:

<img 
  class="gallery__image" 
  v-onload="[image src]"
/>

then just add whatever css animation you want to to occur in your stylesheet:

 /*loaded state*/
.gallery__image {
  opacity: 1;
  transition: opacity 1s linear;
}

 /*unloaded state*/
.gallery__image[data-src]{
  opacity: 0;
}

v-cloak might provide the functionality you are looking for https://v2.vuejs/v2/api/#v-cloak

You can bind to the native onLoad event and call any method in your ponent that you want. demo

<div id="app">
    <img v-for="num in [1,2,3,4]"
         src="http://lorempixel./400/200"
         :onLoad="onLoadHandler()" />
</div>


new Vue({
    el: '#app',
    methods: {
        onLoadHandler: function() {
            alert('hi');
        }
    }
});
发布评论

评论列表(0)

  1. 暂无评论