ccforward / progressive-image

A progressive-image module for Vanilla JavaScript and Vue 1.0+ & 2.0+
https://ccforward.github.io/progressive-image/index.html
MIT License
377 stars 43 forks source link

图片直接进行加载 #1

Open abcdGJJ opened 7 years ago

abcdGJJ commented 7 years ago

按照作者的代码试了一下,发现图片(第二张和第三张)在没有滚动的情况下会自动加载出来,找不到原因

<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();
})()