首页 > 技术文章 > 图片加载淡入淡出效果

sakura-sakura 2017-04-07 15:08 原文

HTML代码

首先是图片标记的写法:

<img data-src="/path/to/image.jpg" alt="">

需要将图片的地址放到 data-src 属性里,而src值填写默认的一张图片。

CSS代码

所有具有data-src属性的图片,我们将其初始显示状态为不可见,通过透明度来调节:

img {
	opacity: 1;
	transition: opacity 0.3s;
}

img[data-src] {
	opacity: 0;
}

这样写的作用是什么?等当图片加载时,你就能看的效果了。

JavaScript代码

我们最终会将 data-src 属性去掉,换成src属性,但这是图片加载成功后的动作:

[].forEach.call(document.querySelectorAll('img[data-src]'), function(img) {
	img.setAttribute('src', img.getAttribute('data-src'));
	img.onload = function() {
		img.removeAttribute('data-src');
	};
});

观看演示
相比起其它各种的图片延迟加载技术,这种方法非常的简单,它几乎不要求其它任何条件,可以用在任何地方,使用起来非常灵活。

当然,简单有简单的好坏,也会因为简单而不足。它不具有图片图片滚动到可视窗口内再加载的功能。最终使用哪种技术,还是要看场景而定。

下面是lazyload.js


var lazyLoad = {
    init: function() {
        var that = this;
        that.onerrorImgUrl = "data-error"; //图片加载失败用什么图片替换
        that.srcStore = "data-src"; //图片真实地址存放的自定义属性
        that.class = "lazy-img"; //惰性加载的图片需要添加的class
        that.sensitivity = 50; //该值越小,惰性越强(加载越少)
        minScroll = 5,
        slowScrollTime = 200;

        document.addEventListener("scroll", function() {
            that.changeimg();
        });

        setTimeout(function() {
            that.trigger();
        }, 100);

    },
    scanImage: function() {
        var that = this;
        var imgList = [];
        var allimg = [].slice.call(document.querySelectorAll('img.' + that.class + ''));
        allimg.forEach(function(ele) {
            if (!that.isLoadedImageCompleted(ele)) {
                imgList.push(ele);
            }
        });

        that.imglistArr = imgList;
    },
    isLoadedImageCompleted: function(ele) {
        return (ele.getAttribute('data-loaded') == '1')
    },
    trigger: function() {
        var that = this;
        eventType = that.isPhone && "touchend" || "scroll";
        that.fireEvent(document, eventType);
        //$(window).trigger(eventType);
    },
    fireEvent: function(element, event) {
        // 其他标准浏览器使用dispatchEvent方法
        var evt = document.createEvent('HTMLEvents');
        // initEvent接受3个参数:
        // 事件类型,是否冒泡,是否阻止浏览器的默认行为
        evt.initEvent(event, true, true);
        return !element.dispatchEvent(evt);
    },
    changeimg: function() {
        function loadYesOrno(img) {
            var windowPageYOffset = window.pageYOffset,
                windowPageYOffsetAddHeight = windowPageYOffset + window.innerHeight,
                imgOffsetTop = img.getBoundingClientRect().top + window.pageYOffset;
            return imgOffsetTop >= windowPageYOffset && imgOffsetTop - that.sensitivity <= windowPageYOffsetAddHeight;
        }

        function loadImg(img, index) {

            var imgUrl = img.getAttribute(that.srcStore);

            img.setAttribute("src", imgUrl);

            img.onload || (img.onload = function() {
                    img.classList.remove(that.class);
                    img.setAttribute('data-loaded', 1)
                    img.removeAttribute('data-src');
                    //$(this).removeClass(that.class).getAttribute('data-loaded',1),
                    that.imglistArr[index] = null;
                    img.onerror = img.onload = null;
                },
                img.onerror = function() {
                    img.src = img.getAttribute(that.onerrorImgUrl);
                    img.classList.remove(that.class);
                    img.classList.add("lazy-err");
                    img.setAttribute('data-loaded', 0);
                    //$(this).removeClass(that.class).getAttribute('data-loaded',0),
                    that.imglistArr[index] = null,
                        img.onerror = img.onload = null
                });

            var newImgStack = [];
            that.imglistArr.forEach(function(ele) {

                //img标签可见并且加载未完成
                if (!that.isLoadedImageCompleted(ele)) {
                    newImgStack.push(ele);
                }
            });
            that.imglistArr = newImgStack;
        }

        var that = this;
        that.scanImage();
        that.imglistArr.forEach(function(val, index) {

            if (!val) return;
            var img = val;
            if (!loadYesOrno(img) || that.isLoadedImageCompleted(img)) return;

            if (!img.getAttribute(that.srcStore)) return;

            loadImg(img, index);
        })

    }
};

推荐阅读