progressive-image
progressive-image copied to clipboard
图片直接进行加载
按照作者的代码试了一下,发现图片(第二张和第三张)在没有滚动的情况下会自动加载出来,找不到原因
<main id="app">
<div class="progressive">
<img class="preview lazy" data-src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/1.jpg" src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/r1.jpg"/>
</div>
<div class="space"></div>
<div class="progressive">
<img class="preview lazy" data-src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/2.jpg" src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/r2.jpg"/>
</div>
<div class="space"></div>
<div class="progressive">
<img class="preview lazy" data-src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/1.jpg" src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/r2.jpg" />
</div>
</main>
class Progressive {
constructor(option) {
this.el = option.el
this.lazyClass = option.lazyClass || 'lazy'
this.removePreview = option.removePreview || false
this.EVENTS = ['scroll', 'wheel', 'mousewheel', 'resize']
this.Util = {
throttle(action, delay) {
let timeout = null
let lastRun = 0
return function () {
if (timeout) {
return
}
const elapsed = Date.now() - lastRun
const context = this
const args = arguments
const runCallback = function () {
lastRun = Date.now()
timeout = false
action.apply(context, args)
}
if (elapsed >= delay) {
runCallback()
} else {
timeout = setTimeout(runCallback, delay)
}
}
},
on(el, ev, fn) {
el.addEventListener(ev, fn)
},
off(el, ev, fn) {
el.removeEventListener(ev, fn)
}
}
this.windowHasBind = false
this.lazy = this.Util.throttle(_ => {
this.fire()
}, 300)
this.animationEvent = this.getAnimationEvent()
}
fire() {
if (!this.windowHasBind) {
this.windowHasBind = true
this.events(window, true)
}
const lazys = document.querySelectorAll(`${this.el} img.${this.lazyClass}`)
const l = lazys.length
if (l > 0) {
for (let i = 0; i < l; i++) {
const rect = lazys[i].getBoundingClientRect()
if (rect.top < window.innerHeight && rect.bottom > 0 && rect.left < window.innerWidth && rect.right > 0) {
this.loadImage(lazys[i])
}
}
} else {
this.windowHasBind = false
this.events(window, false)
}
}
events(el, bind) {
if (bind) {
this.EVENTS.forEach(evt => {
this.Util.on(el, evt, this.lazy)
})
} else {
this.EVENTS.forEach(evt => {
this.Util.off(el, evt, this.lazy)
})
}
}
loadImage(item) {
const img = new Image()
if (item.dataset) {
item.dataset.srcset && (img.srcset = item.dataset.srcset)
item.dataset.sizes && (img.sizes = item.dataset.sizes)
}
img.src = item.dataset.src
img.className = 'origin'
item.classList.remove('lazy')
img.onload = _ => {
this.mountImage(item, img)
}
img.onerror = _ => {
item.classList.add('lazy')
}
}
getAnimationEvent() {
const el = document.createElement('fake')
const animations = {
"animation": "animationend",
"OAnimation": "oAnimationEnd",
"MozAnimation": "animationend",
"WebkitAnimation": "webkitAnimationEnd"
}
for (let a in animations) {
if (el.style[a] !== undefined) {
return animations[a]
}
}
}
mountImage(preview, img) {
const parent = preview.parentNode
parent.appendChild(img).addEventListener(this.animationEvent, e => {
e.target.alt = preview.alt || ''
preview.classList.add('hide')
if (this.removePreview) {
parent.removeChild(preview)
e.target.classList.remove('origin')
}
})
}
}
(function () {
new Progressive({
el: '#app',
lazyClass: 'lazy',
removePreview: true
}).fire();
})()