Skip to content

Commit

Permalink
fix: issue#373 #372
Browse files Browse the repository at this point in the history
  • Loading branch information
hilongjw committed Jun 29, 2019
1 parent 995ca81 commit 6c8d883
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 42 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vue-lazyload",
"version": "1.3.0",
"version": "1.3.1",
"description": "Vue module for lazy-loading images in your vue.js applications.",
"main": "vue-lazyload.js",
"module": "vue-lazyload.esm.js",
Expand Down
20 changes: 13 additions & 7 deletions src/lazy.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
assign,
isObject,
hasIntersectionObserver,
modeType
modeType,
ImageCache
} from './util'

import ReactiveListener from './listener'
Expand Down Expand Up @@ -52,7 +53,7 @@ export default function (Vue) {
observerOptions: observerOptions || DEFAULT_OBSERVER_OPTIONS
}
this._initEvent()

this._imageCache = new ImageCache({ max: 200 })
this.lazyLoadHandler = throttle(this._lazyLoadHandler.bind(this), this.options.throttleWait)

this.setMode(this.options.observer ? modeType.observer : modeType.event)
Expand Down Expand Up @@ -137,7 +138,8 @@ export default function (Vue) {
error,
src,
elRenderer: this._elRenderer.bind(this),
options: this.options
options: this.options,
imageCache: this._imageCache
})

this.ListenerQueue.push(newListener)
Expand Down Expand Up @@ -192,7 +194,8 @@ export default function (Vue) {
if (existItem) {
this._removeListenerTarget(existItem.$parent)
this._removeListenerTarget(window)
remove(this.ListenerQueue, existItem) && existItem.destroy()
remove(this.ListenerQueue, existItem)
existItem.destroy()
}
}

Expand Down Expand Up @@ -337,14 +340,17 @@ export default function (Vue) {
_lazyLoadHandler () {
const freeList = []
this.ListenerQueue.forEach((listener, index) => {
if (!listener.state.error && listener.state.loaded) {
return freeList.push(listener)
if (!listener.el || !listener.el.parentNode) {
freeList.push(listener)
}
const catIn = listener.checkInView()
if (!catIn) return
listener.load()
})
freeList.forEach(vm => remove(this.ListenerQueue, vm))
freeList.forEach(item => {
remove(this.ListenerQueue, item)
item.destroy()
})
}
/**
* init IntersectionObserver
Expand Down
28 changes: 15 additions & 13 deletions src/listener.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import {
noop
} from './util'

let imageCache = {}

// el: {
// state,
// src,
Expand All @@ -14,7 +12,7 @@ let imageCache = {}
// }

export default class ReactiveListener {
constructor ({ el, src, error, loading, bindType, $parent, options, elRenderer }) {
constructor ({ el, src, error, loading, bindType, $parent, options, elRenderer, imageCache }) {
this.el = el
this.src = src
this.error = error
Expand All @@ -31,7 +29,7 @@ export default class ReactiveListener {

this.$parent = $parent
this.elRenderer = elRenderer

this._imageCache = imageCache
this.performanceData = {
init: Date.now(),
loadStart: 0,
Expand All @@ -55,6 +53,7 @@ export default class ReactiveListener {
}

this.state = {
loading: false,
error: false,
loaded: false,
rendered: false
Expand Down Expand Up @@ -102,10 +101,8 @@ export default class ReactiveListener {
*/
checkInView () {
this.getRect()
return (this.rect.top > 0 && this.rect.top < window.innerHeight * this.options.preLoad) ||
(this.rect.bottom > 0 && this.rect.bottom < window.innerHeight * this.options.preLoad) ||
(this.rect.left > 0 && this.rect.left < window.innerWidth * this.options.preLoad) ||
(this.rect.right > 0 && this.rect.right < window.innerWidth * this.options.preLoad)
return (this.rect.top < window.innerHeight * this.options.preLoad && this.rect.bottom > this.options.preLoadTop) &&
(this.rect.left < window.innerWidth * this.options.preLoad && this.rect.right > 0)
}

/*
Expand All @@ -123,14 +120,17 @@ export default class ReactiveListener {
* @return
*/
renderLoading (cb) {
this.state.loading = true
loadImageAsync({
src: this.loading
}, data => {
this.render('loading', false)
this.state.loading = false
cb()
}, () => {
// handler `loading image` load failed
cb()
this.state.loading = false
if (!this.options.silent) console.warn(`VueLazyload log: load failed with loading image(${this.loading})`)
})
}
Expand All @@ -145,11 +145,12 @@ export default class ReactiveListener {
onFinish()
return
}

if (this.state.loaded || imageCache[this.src]) {
if (this.state.rendered && this.state.loaded) return
if (this._imageCache.has(this.src)) {
this.state.loaded = true
onFinish()
return this.render('loaded', true)
this.render('loaded', true)
this.state.rendered = true
return onFinish()
}

this.renderLoading(() => {
Expand All @@ -167,7 +168,8 @@ export default class ReactiveListener {
this.state.error = false
this.record('loadEnd')
this.render('loaded', false)
imageCache[this.src] = 1
this.state.rendered = true
this._imageCache.add(this.src)
onFinish()
}, err => {
!this.options.silent && console.error(err)
Expand Down
26 changes: 26 additions & 0 deletions src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,33 @@ function ArrayFrom (arrLike) {

function noop () {}

class ImageCache {
constructor ({ max }) {
this.options = {
max: max || 100
}
this._caches = []
}

has (key) {
return this._caches.indexOf(key) > -1
}

add (key) {
if (this.has(key)) return
this._caches.push(key)
if (this._caches.length > this.options.max) {
this.free()
}
}

free () {
this._caches.shift()
}
}

export {
ImageCache,
inBrowser,
CustomEvent,
remove,
Expand Down
Loading

0 comments on commit 6c8d883

Please sign in to comment.