原生javascript - 图片滚动按需加载

图片滚动按需加载:在某个区域的图片(自定义的范围,一般是首屏以下的区域),拉动滚动,图片出现在可视范围才开始加载,目的是减少请求,减耗带宽,提高首屏的呈现速度,让用户第一时间看到网页内容,留下美好的第一印象。

讲解:

(一)需要按需加载的img标签,图片的真实地址保存到自定义的属性里,如 'data-src' ,那么src属性用一张1像素透明的图片

(二)把某范围内的img标签元素保存到数组里面

(三)定义一个方法:遍历数组元素,然后判断元素的offsetTop是否在滚动的可视范围内,如果在,交换图片的属性 ('data-src','src'),然后删除这个元素,那么在下次遍历就不存在

load: function () {
        //->全部加装,解除事件
        if (this.imgList.length == 0) {
            this.removeHandler(window, 'scroll', this.fnLoad);
            this.removeHandler(window, 'resize', this.fnLoad);
            return
        }
        var st = document.body.scrollTop || document.documentElement.scrollTop,
            clientH = document.documentElement.clientHeight,
            scrollArea = st + clientH;
        for (var n = 0; n < this.imgList.length; n++) {
            var offsetTop = this.imgList[n].getBoundingClientRect().top + st,
                imgH = this.imgList[n].clientHeight;
            if (scrollArea > (offsetTop - 200) && (imgH + offsetTop) > st) {
                var _src = this.imgList[n].getAttribute(this.holderSrc);
                this.imgList[n].setAttribute('src', _src);
                this.imgList.splice(n, 1); //->删除已经加载完的元素
                n--;
            }
        }
    },

(四)给window对象,scroll 与 resize 添加此事件

(五)用户有可能快速拉滚动条,这样会导致事件的频繁触发,所以需要添加个setTimeout

bind: function (obj, fn) {
        var _this = this;
        return function () {
            if (_this.timer) clearTimeout(_this.timer);
            _this.timer = setTimeout(function () {
                fn.apply(obj, arguments);
            }, 300);
        }
    },

完整代码:

function LazyScroll(opt) {
    this.init(opt);
}

LazyScroll.prototype = {
    init: function (opt) {
        this.setOptions(opt);
        this.load();
        this.fnLoad = this.bind(this, this.load);
        this.addHandler(window, 'scroll', this.fnLoad);
        this.addHandler(window, 'resize', this.fnLoad);
    },
    setOptions: function (opt) {
        this.holderSrc = opt.holderSrc || 'data-src';
        this.wrapId = opt.wrapId;
        this.imgList = [];
        this.timer = null;
        var targets = null;
        if (document.querySelectorAll) {
            targets = document.querySelectorAll("#" + this.wrapId + "img")
        } else {
            targets = document.getElementById(this.wrapId).getElementsByTagName("img")
        }
        var n = 0,
            len = targets.length;
        //->把元素存到数组里
        for (n; n < len; n++) {
            if (targets[n].getAttribute(this.holderSrc)) {
                this.imgList.push(targets[n]);
            }
        }
    },
    load: function () {
        //->全部加装,解除事件
        if (this.imgList.length == 0) {
            this.removeHandler(window, 'scroll', this.fnLoad);
            this.removeHandler(window, 'resize', this.fnLoad);
            return
        }
        var st = document.body.scrollTop || document.documentElement.scrollTop,
            clientH = document.documentElement.clientHeight,
            scrollArea = st + clientH;
        for (var n = 0; n < this.imgList.length; n++) {
            var offsetTop = this.imgList[n].getBoundingClientRect().top + st,
                imgH = this.imgList[n].clientHeight;
            if (scrollArea > (offsetTop - 200) && (imgH + offsetTop) > st) {
                var _src = this.imgList[n].getAttribute(this.holderSrc);
                this.imgList[n].setAttribute('src', _src);
                this.imgList.splice(n, 1); //->删除已经加载完的元素
                n--;
            }
        }
    },
    bind: function (obj, fn) {
        var _this = this;
        return function () {
            if (_this.timer) clearTimeout(_this.timer);
            _this.timer = setTimeout(function () {
                fn.apply(obj, arguments);
            }, 300);
        }
    },
    addHandler: function (node, type, fn) {
        if (node.addEventListener) {
            node.addEventListener(type, fn, false);
        } else {
            node.attachEvent('on' + type, function () {
                fn.apply(node, arguments);
            });
        }
    },
    removeHandler: function (node, type, fn) {
        if (node.addEventListener) {
            node.removeEventListener(type, fn, false);
        } else {
            node.detachEvent("on" + type, fn);
        }
    }
}
<body id="body">
    <div style="background-color:#ccc;height:1000px;">1</div>
    <img src="xxxx" width="990" height="90" data-src="http://dummyimage.com/990x90/333/fff" alt="" />
    <img src="xxxx" width="990" height="90" data-src="http://dummyimage.com/990x90/333/fff" alt="" />
    <img src="xxxx" width="990" height="90" data-src="http://dummyimage.com/990x90/333/fff" alt="" />
    <img src="xxxx" width="990" height="90" data-src="http://dummyimage.com/990x90/333/fff" alt="" />
    <img src="xxxx" width="990" height="90" data-src="http://dummyimage.com/990x90/333/fff" alt="" />
    <img src="xxxx" width="990" height="90" data-src="http://dummyimage.com/990x90/333/fff" alt="" />
    <img src="xxxx" width="990" height="90" data-src="http://dummyimage.com/990x90/333/fff" alt="" />

    <script type="text/javascript" src="myLazyScroll.js"></script>
    <script>
        new LazyScroll({'wrapId': 'body'});
    </script>
</body>

 

二、使用jQuery的lazyload.js

使用方法:

(一)引用jquery和jquery.lazyload.js到你的页面

 

 

 

 

三、移动端的可以参考 echo.js 

 

参考博客:

一、http://www.cnblogs.com/focuslgy/p/3194502.html

二、jQuery图片延迟加载插件jQuery.lazyload

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的原生JS实现图片滚动加载的demo源码: HTML: ```html <div id="container"> <img src="placeholder.jpg" data-src="image1.jpg" alt=""> <img src="placeholder.jpg" data-src="image2.jpg" alt=""> <img src="placeholder.jpg" data-src="image3.jpg" alt=""> <img src="placeholder.jpg" data-src="image4.jpg" alt=""> <img src="placeholder.jpg" data-src="image5.jpg" alt=""> <img src="placeholder.jpg" data-src="image6.jpg" alt=""> <img src="placeholder.jpg" data-src="image7.jpg" alt=""> <img src="placeholder.jpg" data-src="image8.jpg" alt=""> <img src="placeholder.jpg" data-src="image9.jpg" alt=""> <img src="placeholder.jpg" data-src="image10.jpg" alt=""> </div> ``` CSS: ```css #container { width: 600px; height: 400px; overflow-y: auto; } img { width: 100%; margin-bottom: 10px; } ``` JS: ```javascript // 获取容器和所有图片 var container = document.getElementById('container'); var images = container.getElementsByTagName('img'); // 加载图片 function loadImg(img) { var imgSrc = img.getAttribute('data-src'); img.src = imgSrc; } // 判断图片是否在可视区域内 function isInViewport(img) { var rect = img.getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); } // 加载可视区域内的图片 function loadVisibleImages() { for (var i = 0; i < images.length; i++) { if (isInViewport(images[i])) { loadImg(images[i]); } } } // 初始化,加载可视区域内的图片 loadVisibleImages(); // 滚动加载可视区域内的图片 container.addEventListener('scroll', function() { loadVisibleImages(); }); ``` 在上面的代码中,我们首先通过`document.getElementById`和`container.getElementsByTagName`获取到容器和所有的图片元素。然后,我们定义了两个函数:`loadImg`和`isInViewport`,分别用于加载图片和判断图片是否在可视区域内。`loadVisibleImages`函数用来加载可视区域内的图片,我们在初始化时先调用一次,然后在容器滚动时也会调用。最后,我们通过`container.addEventListener`给容器添加一个滚动事件监听器,以便在容器滚动加载可视区域内的图片

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值