图片懒加载插件实例分享(含解析)


Posted in Javascript onJanuary 09, 2017

在面试的时候有面试官问我,懒加载这个插件你有没有想到如何去优化?又间接问我函数节流的问题,嘿嘿,今天就更新下这个插件,顺便应用下函数节流(throttle),先直接上下代码,含解析

/*
 * 函数功能:函数节流
 * fn 需要调用的函数
 * delay 函数需要延迟处理的时间
 * mustRunDelay 超过该时间,函数一定会执行
 * */
 var throttle = function (fn, delay, mustRunDelay) {
 var timer; //使用闭包存储timer
 var t_start;
 //闭包返回的函数
 return function (val) {
 var args = arguments, t_curr = +new Date(); //使用+new Date() 将字符串转换成数字
 clearTimeout(timer);
 if (!t_start) { // 使用!t_start 如果t_start=undefined或者null 则为true
 t_start = t_curr;
 }
 if (t_curr - t_start >= mustRunDelay) {
 fn.apply(null, args);
 t_start = t_curr;
 } else {
 timer = setTimeout(function () {
  fn.apply(null, args);
 }, delay);
 }
 }
 };
 /*使用方法*/
 var throttle1 = throttle(fn, 500, 4000);
 //在该需要调用的函数内部调用此函数
 throttle1(val); //此处传人的参数为以上fn需要传人的参数

至于函数节流具体的好处,常用的场景,以下文章说得非常清楚,我就不再说啦~

很多网站都会用到‘图片懒加载'这种方式对网站进行优化,即延迟加载图片或符合某些条件才开始加载图片。于是心血来潮,决定自己手动写一下'图片懒加载‘插件。

使用这个技术有什么显著的优点?

比如一个页面中有很多图片,如淘宝首页等等,一个页面有100多的图片,如果一上来就发送这么多请求,页面加载就会很漫长,如果js文件都放在了文档的底部,恰巧页面的头部又依赖这个js文件,那就不好办了。用户感觉这个页面就会很卡。

懒加载原理:浏览器会自动对页面中的img标签的src属性发送请求并下载图片。通过动态改变img的src属性实现。

当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成loading图片地址(这样就只需请求一次)

等到一定条件(这里是页面滚动到一定区域),用实际存放img地址的laze-load属性的值去替换src属性,即可实现'懒加载'。

//即使img的src值为空,浏览器也会对服务器发送请求。所以平时做项目的时候,如果img没有用到src,就不要出现src这个属性

先上三个重要的知识点

1.获取屏幕可视窗口大小:

document.documentElement.clientHeight 标准浏览器及低版本IE标准模式

document.body.clientHeight 低版本混杂模式

2.元素相对于文档document顶部

element.offsetTop

3.滚动条滚动的距离

document.documentElement.scrollTop   兼容ie低版本的标准模式

document.body.scrollTop 兼容混杂模式;

滚动加载:当图片出现在可视区域时,动态加载该图片。

原理:当图片元素顶部是否在可视区域内,(图片相对于文档document顶部-滚动条滚动的距离)< 可视窗口大小,改变该img的src属性 

实现原理:

1.首先从所有相关元素中找出需要延时加载的元素,放在element_obj数组中。

function initElementMap() {
 var el = document.getElementsByTagName('img');
 for (var j = 0, len2 = el.length; j < len2; j++) {
 //判断当前的img是否加载过了,或者有lazy_src标志 [未完成]
 if (typeof (el[j].getAttribute("lazy_src"))) {
 element_obj.push(el[j]);
 download_count++;
 }
 }
 }

2.判断数组中的img对象,若满足条件,则改变src属性

function lazy() {
 if (!download_count) return;
 var innerHeight = getViewport();
 for (var i = 0, len = element_obj.length; i < len; i++) {
//得到图片相对document的距上距离
 var t_index = getElementViewTop(element_obj[i]); 
 if (t_index - getScrollTop() < innerHeight) {
 element_obj[i].src = element_obj[i].getAttribute("lazy-src");
 delete element_obj[i];
 download_count--;
 }
 }
}

3.滚动的时候触发事件,1000毫秒后执行lazy()方法。

window.onscroll = window.onload = function () {
 setTimeout(function () {
 lazy();
 }, 1000)
 }

整部分代码位于闭包自执行函数中。相应的方法放在init中。

var lazyLoad = (function () { 
 function init() {
 initElementMap();
 lazy();
 };
 return {
 init: init 
 }
})();

使用格式 :src填默认loading图片地址,真实的图片地址填在lazy-src属性里,切记需指定宽高。在外部调用  lazyLoad.init();

全部的代码以及例子已经上传到github上了,地址是:https://github.com/beidan/lazeLoadImg,欢迎star

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
利用Ext Js生成动态树实例代码
Sep 08 Javascript
JS实现图片横向滚动效果示例代码
Sep 04 Javascript
jQuery学习笔记之 Ajax操作篇(三) - 过程处理
Jun 23 Javascript
jQuery过滤HTML标签并高亮显示关键字的方法
Aug 07 Javascript
javascript类型系统 Window对象学习笔记
Jan 07 Javascript
基于BootStrap与jQuery.validate实现表单提交校验功能
Dec 22 Javascript
jQuery插件HighCharts绘制2D饼图效果示例【附demo源码下载】
Mar 21 jQuery
详解Vuejs2.0 如何利用proxyTable实现跨域请求
Aug 03 Javascript
在vue项目中集成graphql(vue-ApolloClient)
Sep 08 Javascript
vue中promise的使用及异步请求数据的方法
Nov 08 Javascript
JQuery+Bootstrap 自定义全屏Loading插件的示例demo
Jul 03 jQuery
vue+iview分页组件的封装
Nov 17 Vue.js
微信小程序 数据封装,参数传值等经验分享
Jan 09 #Javascript
简单实现jQuery多选框功能
Jan 09 #Javascript
微信小程序开发之Tabbar实例详解
Jan 09 #Javascript
javascript监听页面刷新和页面关闭事件方法详解
Jan 09 #Javascript
JS获得多个同name 的input输入框的值的实现方法
Jan 09 #Javascript
微信小程序去哪里找 小程序到底如何使用(附小程序名单)
Jan 09 #Javascript
原生Javascript插件开发实践
Jan 09 #Javascript
You might like
Smarty中调用FCKeditor的方法
2014/10/27 PHP
PHP命名空间和自动加载类
2016/04/03 PHP
jquery 批量上传图片实现代码
2010/01/28 Javascript
解决Extjs上传图片无法预览的解决方法
2012/03/22 Javascript
JavaScript中函数表达式和函数声明及函数声明与函数表达式的不同
2015/11/15 Javascript
Extjs gridpanel 中的checkbox(复选框)根据某行的条件不能选中的解决方法
2017/02/17 Javascript
JavaScript运动框架 链式运动到完美运动(五)
2017/05/18 Javascript
angularJs中datatable实现代码
2017/06/03 Javascript
vue中component组件的props使用详解
2017/09/04 Javascript
Angular数据绑定机制原理
2018/04/17 Javascript
Vue.js 踩坑记之双向绑定
2018/05/03 Javascript
对vux点击事件的优化详解
2018/08/28 Javascript
微信小程序全选多选效果实现代码解析
2020/01/21 Javascript
OpenLayers实现图层切换控件
2020/09/25 Javascript
使用Python的PIL模块来进行图片对比
2016/02/18 Python
详谈Python2.6和Python3.0中对除法操作的异同
2017/04/28 Python
在Windows中设置Python环境变量的实例讲解
2018/04/28 Python
python中字符串内置函数的用法总结
2018/09/13 Python
Python实现随机创建电话号码的方法示例
2018/12/07 Python
计算机二级python学习教程(3) python语言基本数据类型
2019/05/16 Python
python用线性回归预测股票价格的实现代码
2019/09/04 Python
python制作朋友圈九宫格图片
2019/11/03 Python
Python JSON编解码方式原理详解
2020/01/20 Python
python如何把字符串类型list转换成list
2020/02/18 Python
python 动态渲染 mysql 配置文件的示例
2020/11/20 Python
HTML5新特性之type=file文件上传功能
2018/02/02 HTML / CSS
动漫专业高职生职业生涯规划书
2014/02/15 职场文书
幼儿园母亲节活动方案
2014/03/10 职场文书
三好学生演讲稿范文
2014/04/26 职场文书
幼儿园六一活动总结
2014/08/27 职场文书
党支部书记四风问题整改措施
2014/09/24 职场文书
离婚协议书范本(2014版)
2014/09/28 职场文书
关爱留守儿童捐款倡议书
2015/04/27 职场文书
看古人们是如何赞美老师的?
2019/07/08 职场文书
《水浒传》读后感3篇(范文)
2019/09/19 职场文书
为什么不建议在go项目中使用init()
2021/04/12 Golang