Giter Site home page Giter Site logo

hilongjw / vue-lazyload Goto Github PK

View Code? Open in Web Editor NEW
8.0K 96.0 869.0 4.74 MB

A Vue.js plugin for lazyload your Image or Component in your application.

Home Page: http://hilongjw.github.io/vue-lazyload/

License: MIT License

JavaScript 98.93% Shell 0.60% TypeScript 0.47%
vue-lazyload vue lazyload

vue-lazyload's Introduction

Vue-Lazyload

Build Status npm version npm downloads npm license PRs Welcome CDNJS version

Vue module for lazyloading images in your applications. Some of goals of this project worth noting include:

  • Be lightweight, powerful and easy to use
  • Work on any image type
  • Add loading class while image is loading
  • Supports both of Vue 1.0 and Vue 2.0

For Vue 3

Please use [email protected], see here

Table of Contents

Demo

Demo

Requirements

Installation

npm

$ npm i vue-lazyload -S

yarn

$ yarn add vue-lazyload

CDN

CDN: https://unpkg.com/vue-lazyload/vue-lazyload.js

<script src="https://unpkg.com/vue-lazyload/vue-lazyload.js"></script>
<script>
  Vue.use(VueLazyload)
  ...
</script>

Usage

main.js:

import Vue from 'vue'
import App from './App.vue'
import VueLazyload from 'vue-lazyload'

Vue.use(VueLazyload)

// or with options
const loadimage = require('./assets/loading.gif')
const errorimage = require('./assets/error.gif')

Vue.use(VueLazyload, {
  preLoad: 1.3,
  error: errorimage,
  loading: loadimage,
  attempt: 1
})

new Vue({
  el: 'body',
  components: {
    App
  }
})

template:

<ul>
  <li v-for="img in list">
    <img v-lazy="img.src" >
  </li>
</ul>

use v-lazy-container work with raw HTML

<div v-lazy-container="{ selector: 'img' }">
  <img data-src="//domain.com/img1.jpg">
  <img data-src="//domain.com/img2.jpg">
  <img data-src="//domain.com/img3.jpg">  
</div>

custom error and loading placeholder image

<div v-lazy-container="{ selector: 'img', error: 'xxx.jpg', loading: 'xxx.jpg' }">
  <img data-src="//domain.com/img1.jpg">
  <img data-src="//domain.com/img2.jpg">
  <img data-src="//domain.com/img3.jpg">  
</div>
<div v-lazy-container="{ selector: 'img' }">
  <img data-src="//domain.com/img1.jpg" data-error="xxx.jpg">
  <img data-src="//domain.com/img2.jpg" data-loading="xxx.jpg">
  <img data-src="//domain.com/img3.jpg">  
</div>

Constructor Options

key description default options
preLoad proportion of pre-loading height 1.3 Number
error src of the image upon load fail 'data-src' String
loading src of the image while loading 'data-src' String
attempt attempts count 3 Number
listenEvents events that you want vue listen for ['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend', 'touchmove'] Desired Listen Events
adapter dynamically modify the attribute of element { } Element Adapter
filter the image's listener filter { } Image listener filter
lazyComponent lazyload component false Lazy Component
dispatchEvent trigger the dom event false Boolean
throttleWait throttle wait 200 Number
observer use IntersectionObserver false Boolean
observerOptions IntersectionObserver options { rootMargin: '0px', threshold: 0.1 } IntersectionObserver
silent do not print debug info true Boolean

Desired Listen Events

You can configure which events you want vue-lazyload by passing in an array of listener names.

Vue.use(VueLazyload, {
  preLoad: 1.3,
  error: 'dist/error.png',
  loading: 'dist/loading.gif',
  attempt: 1,
  // the default is ['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend']
  listenEvents: [ 'scroll' ]
})

This is useful if you are having trouble with this plugin resetting itself to loading when you have certain animations and transitions taking place

Image listener filter

dynamically modify the src of image

Vue.use(vueLazy, {
    filter: {
      progressive (listener, options) {
          const isCDN = /qiniudn.com/
          if (isCDN.test(listener.src)) {
              listener.el.setAttribute('lazy-progressive', 'true')
              listener.loading = listener.src + '?imageView2/1/w/10/h/10'
          }
      },
      webp (listener, options) {
          if (!options.supportWebp) return
          const isCDN = /qiniudn.com/
          if (isCDN.test(listener.src)) {
              listener.src += '?imageView2/2/format/webp'
          }
      }
    }
})

Element Adapter

Vue.use(vueLazy, {
    adapter: {
        loaded ({ bindType, el, naturalHeight, naturalWidth, $parent, src, loading, error, Init }) {
            // do something here
            // example for call LoadedHandler
            LoadedHandler(el)
        },
        loading (listender, Init) {
            console.log('loading')
        },
        error (listender, Init) {
            console.log('error')
        }
    }
})

IntersectionObserver

use Intersection Observer to to improve performance of a large number of nodes.

Vue.use(vueLazy, {
  // set observer to true
  observer: true,

  // optional
  observerOptions: {
    rootMargin: '0px',
    threshold: 0.1
  }
})

Lazy Component

Vue.use(VueLazyload, {
  lazyComponent: true
});
<lazy-component @show="handler">
  <img class="mini-cover" :src="img.src" width="100%" height="400">
</lazy-component>

<script>
  {
    ...
    methods: {
      handler (component) {
        console.log('this component is showing')
      }
    }

  }
</script>

Use in list

<lazy-component v-for="(item, index) in list" :key="item.src" >
  <img class="mini-cover" :src="item.src" width="100%" height="400">
</lazy-component>

Implementation

Basic

vue-lazyload will set this img element's src with imgUrl string

<script>
export default {
  data () {
    return {
      imgObj: {
        src: 'http://xx.com/logo.png',
        error: 'http://xx.com/error.png',
        loading: 'http://xx.com/loading-spin.svg'
      },
      imgUrl: 'http://xx.com/logo.png' // String
    }
  }
}
</script>

<template>
  <div ref="container">
     <img v-lazy="imgUrl"/>
     <div v-lazy:background-image="imgUrl"></div>

     <!-- with customer error and loading -->
     <img v-lazy="imgObj"/>
     <div v-lazy:background-image="imgObj"></div>

     <!-- Customer scrollable element -->
     <img v-lazy.container ="imgUrl"/>
     <div v-lazy:background-image.container="img"></div>

    <!-- srcset -->
    <img v-lazy="'img.400px.jpg'" data-srcset="img.400px.jpg 400w, img.800px.jpg 800w, img.1200px.jpg 1200w">
    <img v-lazy="imgUrl" :data-srcset="imgUrl' + '?size=400 400w, ' + imgUrl + ' ?size=800 800w, ' + imgUrl +'/1200.jpg 1200w'" />
  </div>
</template>

CSS state

There are three states while img loading

loading loaded error

<img src="imgUrl" lazy="loading">
<img src="imgUrl" lazy="loaded">
<img src="imgUrl" lazy="error">
<style>
  img[lazy=loading] {
    /*your style here*/
  }
  img[lazy=error] {
    /*your style here*/
  }
  img[lazy=loaded] {
    /*your style here*/
  }
  /*
  or background-image
  */
  .yourclass[lazy=loading] {
    /*your style here*/
  }
  .yourclass[lazy=error] {
    /*your style here*/
  }
  .yourclass[lazy=loaded] {
    /*your style here*/
  }
</style>

Methods

Event Hook

vm.$Lazyload.$on(event, callback) vm.$Lazyload.$off(event, callback) vm.$Lazyload.$once(event, callback)

  • $on Listen for a custom events loading, loaded, error
  • $once Listen for a custom event, but only once. The listener will be removed once it triggers for the first time.
  • $off Remove event listener(s).

vm.$Lazyload.$on

Arguments:

  • {string} event
  • {Function} callback

Example

vm.$Lazyload.$on('loaded', function ({ bindType, el, naturalHeight, naturalWidth, $parent, src, loading, error }, formCache) {
  console.log(el, src)
})

vm.$Lazyload.$once

Arguments:

  • {string} event
  • {Function} callback

Example

vm.$Lazyload.$once('loaded', function ({ el, src }) {
  console.log(el, src)
})

vm.$Lazyload.$off

If only the event is provided, remove all listeners for that event

Arguments:

  • {string} event
  • {Function} callback

Example

function handler ({ el, src }, formCache) {
  console.log(el, src)
}
vm.$Lazyload.$on('loaded', handler)
vm.$Lazyload.$off('loaded', handler)
vm.$Lazyload.$off('loaded')

LazyLoadHandler

vm.$Lazyload.lazyLoadHandler

Manually trigger lazy loading position calculation

Example

this.$Lazyload.lazyLoadHandler()

Performance

this.$Lazyload.$on('loaded', function (listener) {
  console.table(this.$Lazyload.performance())
})

performance-demo

Dynamic switching pictures

 <img v-lazy="lazyImg" :key="lazyImg.src">

Authors && Contributors

License

The MIT License

vue-lazyload's People

Contributors

6ml avatar biluochun avatar blue0728 avatar caozhong1996 avatar cookfront avatar dail avatar dnrsm avatar dota17 avatar heww avatar hilongjw avatar iliyazelenko avatar imcvampire avatar jialingc avatar jounqin avatar kenshin-liu avatar leejisoo860911 avatar leopoldthecoder avatar llissery avatar maggiehe avatar mping avatar muwoo avatar peng avatar pioneer-linzi avatar robinck avatar songbug1024 avatar taoxhsmile avatar whwnow avatar yugasun avatar yuzhouzhijia520 avatar zackery-chung avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-lazyload's Issues

var winH = window.screen.availWidth??

是不是应该 var winH = window.screen.availHeight

而且没有考虑移动端DPR变化的情况,我们根据DPR做适配了,所以后面还要乘以window.devicePixelRatio

Can't get it to work on Vue 2.0.5

Hi.

I am unable to get this plugin to work in Vue 2.0.5

// Initialization
import Vue from 'vue';
import VueLazyload from 'vue-lazyload';

Vue.use(VueLazyload);

My .vue template file

<template>
    <a v-on:click="alert('clicked')">
        <img v-lazy="imgUrl" :alt="Image alt text">
    </a>
</template>

<script>
    export default {
        data(){
            return {
                imgUrl: 'http://vignette4.wikia.nocookie.net/warframe/images/2/26/Derelict_Black.png/revision/latest?cb=20140914094121'
            }
        }
</script>

The generated output:

<a><img alt="Image alt text"></a>

And the image is never loaded

File size too large.

When using webpack this is adding 34kb too my app file (not minified). But considering it's only 206kb before and 242kb after this is still huge increase. Even minified it would be around 15kb. I guess from using the promise lib? Is it necessary to include all this extra baggage?

SVG animation

SVG's SMIL animations (<animate>, <set>, etc.) are deprecated and will be removed. Please use CSS animations or Web animations instead.

往前追加数据,list中图片状态不改变

有一个list,下拉获取历史消息,需要将新数据插入到list前面,因为之前已经对list中图片作了处理,再次更新list数据,前面追加的图片显示的还是历史图片

问题

两个页面反复切换后,未加载的图片会重复添加到listeners

能否支持 v-lazy="{{ data.img }}?from=x1"

这种方式无法在 图片后添加参数

有时候,希望在生成的图片地址后增加参数,
如图片是 1.jpg

vue-lazyload 处理后变成了

但我想在客户端动态的改变参数

有办法吗

删除列表中的一项时报错

我通过v-for生成的列表,用了vue-lazyload,当我操作想删除列表中的一项时报下面的错?请问有方法解决吗?
vue.common.js:1019 [Vue warn]: Failed to resolve directive: lazy (found in component: )
vue-lazyload.es5.js:112 Uncaught TypeError: Cannot read property 'el' of undefined

在微信 WebView 中使用时 img 的背景先是会显示黑色

滚动到未加载图片的 img 处,图片背景会显示为黑色,然后再加载图片。仅在微信的 WebView 中发现有这个问题,其余浏览器环境均正常。试过 !important 之类的方式设置 background-color,问题仍然存在。

模板中的使用方式:

<img v-lazy="photoUrl">

webpack UglifyJsPlugin 插件压缩 vue-lazyload 报错

ERROR in build.bf062f81a70c821ad4dc.js from UglifyJs
SyntaxError: Unexpected token: name (last) [./~/vue-lazyload/vue-lazyload.es5.js:22,0]

vue-lazyload.es5.js:22,0:

const debounce = function(action, idle) {
let last
return function() {
let args = arguments
clearTimeout(last)
last = setTimeout(() => {
action.apply(this, args)
}, idle)
}
}

bug

_.on('transitionend', lazyLoadHandler); => _.off('transitionend', lazyLoadHandler);

Use without webpack

Is there anyway to use this without webpack (standalone in browser)

I tried including vue-lazyload-es5.js but Vue.lazyload is not defined

无法触发加载事件

vue-lazyload Version: 0.4.2
Demo:http://getcrx.cn
操作:

  1. 打开页面,可以看到第一屏图标加载;
  2. 在搜索框进行搜索,比如输入 json,搜索结果中的图标没能正常加载

搜索的实现方式:

<div class="item" v-for="item in list | filterBy keyword in 'name' 'introduce' 'app_id' ">
    <img v-lazy="item.logo">
</div>

Safari Desktop and Mobile issues

Hi,

I'm having a couple of issues that I hope you can help with, firstly the code at the bottom of this issue is throwing an error on Safari (on MBP)

SyntaxError: Unexpected use of reserved word 'let' in strict mode

img: new Set(),
    /* set the img show with it state */
    show() {
      let self = this; <- this line

Also get the below error on Safari mobile (iOS iPhone 6S)

SyntaxError: Unexpected token '('. Expected a ':' following the property name 'show'.

img: new Set(),
    /* set the img show with it state */
    show() { <- this line

The same code works on Chrome on my MBP

This is in my js file

var Vue = require('vue');
Vue.use(require('vue-resource'));
var LazyLoad = require('vue-lazyload');
Vue.use(LazyLoad, {
    error: '/assets/img/trans-1x1.png',
    loading: '/assets/img/trans-1x1.png'
});

Then in my html I have

<img :height="goal.medias[0].size.height" :width="goal.medias[0].size.width" v-lazy="goal.medias[0].file_path + '/' + goal.medias[0].file_name +'?w=450'" :alt="goal.title + ' | iGerit'">

README.md

根据README.md 的使用说明,我在实际的例子里lazyload Img 并没有预想那样工作,请问有具体的实例吗?
一下是使用lazyload component

<template>
<section >
        <div class="luxury-items" v-for="item in list" track-by="$index">
            <a v-bind:href="item.commodity_link">
                <div class="commodity-img"><img v-lazy="item"></div>
           </a>
        </div>
    </section>
</template>
<script>
   import Vue from 'vue';
    import lazyload from 'vue-lazyload';
    Vue.use(lazyload, {
    error: 'dist/error.png',
    loading: 'dist/loading.gif',
    try: 3 // default 1
   })
  export default {
  data () {
    return {
      list: [
          'http://fuss10.elemecdn.com/b/18/0678e57cb1b226c04888e7f244c20jpeg.jpeg',
          'http://fuss10.elemecdn.com/3/1e/42634e29812e6594c98a89e922c60jpeg.jpeg',
          'http://fuss10.elemecdn.com/1/c5/95c37272d3e554317dcec1e17a9f5jpeg.jpeg',
          'http://fuss10.elemecdn.com/7/85/e478e4b26af74f4539c79f31fde80jpeg.jpeg',
          'http://fuss10.elemecdn.com/b/df/b630636b444346e38cef6c59f6457jpeg.jpeg',
          'http://fuss10.elemecdn.com/7/a5/596ab03934612236f807b92906fd8jpeg.jpeg',
      ]
    }
  }
}
</script>

滚动监听的容器现在是window,可否修改为div

var _ = {
on: function on(type, func) {
Init.el.addEventListener(type, func);
},
off: function off(type, func) {
Init.el.removeEventListener(type, func);
}
};
var onListen = function onListen(start) {
Init.el = document.querySelector(Options.el) || window;
}
我现在这样改不知道对不对。

如果懒加载使用本地图片

发现目前只能使用绝对路径的图片。

某些原因,需要懒加载的图片是本地的一些资源,通过相对路径的方式引入./img/pic1.jpg

这个可以实现吗

bug: 如果绑定的el不是window, 而是其它dom,在bind时,parentEl并没有在domcument中,这时就会有问题,图片始终Load不出来

<div class="pic" v-lazy:background-image.j-home-index="item"></div>

if (binding.modifiers) { parentEl = window.document.getElementById(Object.keys(binding.modifiers)[0]) //==> null }

把� 源 码 bind改成 inserted这样就正常了:
if (isVueNext) { Vue.directive('lazy', { // bind: addListener, inserted: addListener, update: addListener, componentUpdated: lazyLoadHandler, unbind : componentWillUnmount }) }

Support custom container

I have user list with avatars, but this list not in window so it will be cool if directive have option to provide custom container.

在滚动条滚动的时候无法显示图片

在滚动条滚动的过程中,即使滚动条已经到了指定的位置,图片占位符已经出现在window上,但是图片仍然不会加载出来,一定要在滚动条静止后才开始显示图片,我觉得这是一个可以优化的地方。

I suspect this does not play nice with vue-router

lazy-loading seems to work fine on the first route when using vue-router. However, when you navigate to another route, only the images that load up in the viewport will load. The rest continue to show the loading image.

Edit: Actually, I just updated to your most recent commit and it seems to be working nicely now. Thank you! 👍

orderBy problem

when vue-lazyload be used,the oderBy function works not,that mean the Buffer can't be refresh

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.