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


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 相关文章推荐
网站页面自动跳转实现方法PHP、JSP(上)
Aug 01 Javascript
获得所有表单值的JQuery实现代码[IE暂不支持]
May 24 Javascript
js 跳出页面的frameset框架示例介绍
Dec 23 Javascript
js showModalDialog参数的使用详解
Jan 07 Javascript
为什么JS中eval处理JSON数据要加括号
Apr 13 Javascript
js日期范围初始化得到前一个月日期的方法
May 05 Javascript
javascript自动恢复文本框点击清除后的默认文本
Jan 12 Javascript
javascript实现的左右无缝滚动效果
Sep 19 Javascript
vue-router 路由基础的详解
Oct 17 Javascript
vue根据进入的路由进行原路返回的方法
Sep 26 Javascript
浅谈Angular单元测试总结
Mar 22 Javascript
编写更好的JavaScript条件式和匹配条件的技巧(小结)
Jun 27 Javascript
微信小程序 数据封装,参数传值等经验分享
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
关于php循环跳出的问题
2013/07/01 PHP
windows7下安装php的php-ssh2扩展教程
2014/07/04 PHP
PHP PDOStatement对象bindpram()、bindvalue()和bindcolumn之间的区别
2014/11/20 PHP
php获取从html表单传递数组的方法
2015/03/20 PHP
PHP中的类型约束介绍
2015/05/11 PHP
php时间函数用法分析
2016/05/28 PHP
php多线程并发实现方法
2016/09/30 PHP
phpcms实现验证码替换及phpcms实现全站搜索功能教程详解
2017/12/13 PHP
laravel框架使用极光推送消息操作示例
2020/02/15 PHP
javascript错误的认识不用关心内存管理
2012/12/15 Javascript
一个简单的JS鼠标悬停特效具体方法
2013/06/17 Javascript
javascript简单事件处理和with用法介绍
2013/09/16 Javascript
js控制TR的显示隐藏
2016/03/04 Javascript
利用jQuery实现CheckBox全选/全不选/反选的简单代码
2016/05/31 Javascript
vue.js之vue-cli脚手架的搭建详解
2017/05/05 Javascript
用最简单的方法判断JavaScript中this的指向(推荐)
2017/09/04 Javascript
nodejs基础之多进程实例详解
2018/12/27 NodeJs
使用nodejs分离html文件里的js和css详解
2019/04/12 NodeJs
vue中在vuex的actions中请求数据实例
2019/11/08 Javascript
javascript实现贪吃蛇游戏(娱乐版)
2020/08/17 Javascript
JS获取当前时间戳方法解析
2020/08/29 Javascript
[06:23]2014DOTA2西雅图国际邀请赛 小组赛7月12日TOPPLAY
2014/07/12 DOTA
[01:27:43]VGJ.S vs TNC Supermajor 败者组 BO3 第三场 6.6
2018/06/07 DOTA
Python中的anydbm模版和shelve模版使用指南
2015/07/09 Python
Python基于PycURL实现POST的方法
2015/07/25 Python
Python使用matplotlib填充图形指定区域代码示例
2018/01/16 Python
python树莓派红外反射传感器
2019/01/21 Python
pytorch的batch normalize使用详解
2020/01/15 Python
Python编程快速上手——疯狂填词程序实现方法分析
2020/02/29 Python
python如何将图片转换素描画
2020/09/08 Python
北美最大的零售退货翻新商:VIP Outlet
2019/11/21 全球购物
广告学专业应届生求职信
2013/10/01 职场文书
奶茶专卖店创业计划书
2014/01/18 职场文书
2014医学院领导班子对照检查材料思想汇报
2014/09/19 职场文书
简单实现一个手持弹幕功能+文字抖动特效
2021/03/31 HTML / CSS
MySQL RC事务隔离的实现
2022/03/31 MySQL