1 /* 2 * 函数功能:函数节流 3 * fn 须要调用的函数 4 * delay 函数须要延迟处理的时间 5 * mustRunDelay 超过该时间,函数必定会执行 6 * */ 7 var throttle = function (fn, delay, mustRunDelay) { 8 var timer; //使用闭包存储timer 9 var t_start; 10 //闭包返回的函数 11 return function (val) { 12 var args = arguments, t_curr = +new Date(); //使用+new Date() 将字符串转换成数字 13 clearTimeout(timer); 14 if (!t_start) { // 使用!t_start 若是t_start=undefined或者null 则为true 15 t_start = t_curr; 16 } 17 if (t_curr - t_start >= mustRunDelay) { 18 fn.apply(null, args); 19 t_start = t_curr; 20 } else { 21 timer = setTimeout(function () { 22 fn.apply(null, args); 23 }, delay); 24 } 25 } 26 }; 27 28 /*使用方法*/ 29 var throttle1 = throttle(fn, 500, 4000); 30 //在该须要调用的函数内部调用此函数 31 throttle1(val); //此处传人的参数为以上fn须要传人的参数
至于函数节流具体的好处,经常使用的场景,如下文章说得很是清楚,我就再也不说啦~javascript
好比一个页面中有不少图片,如淘宝首页等等,一个页面有100多的图片,若是一上来就发送这么多请求,页面加载就会很漫长,若是js文件都放在了文档的底部,恰巧页面的头部又依赖这个js文件,那就很差办了。用户感受这个页面就会很卡。html
当访问一个页面的时候,先把img元素或是其余元素的背景图片路径替换成loading图片地址(这样就只需请求一次)java
//即便img的src值为空,浏览器也会对服务器发送请求。因此平时作项目的时候,若是img没有用到src,就不要出现src这个属性 git
element.offsetTopgithub
document.documentElement.scrollTop 兼容ie低版本的标准模式 面试
document.body.scrollTop 兼容混杂模式;数组
1 function initElementMap() { 2 var el = document.getElementsByTagName('img'); 3 for (var j = 0, len2 = el.length; j < len2; j++) { 4 //判断当前的img是否加载过了,或者有lazy_src标志 [未完成] 5 if (typeof (el[j].getAttribute("lazy_src"))) { 6 element_obj.push(el[j]); 7 download_count++; 8 } 9 } 10 }
2.判断数组中的img对象,若知足条件,则改变src属性浏览器
1 function lazy() { 2 if (!download_count) return; 3 var innerHeight = getViewport(); 4 for (var i = 0, len = element_obj.length; i < len; i++) { 5 //获得图片相对document的距上距离 6 var t_index = getElementViewTop(element_obj[i]); 7 if (t_index - getScrollTop() < innerHeight) { 8 element_obj[i].src = element_obj[i].getAttribute("lazy-src"); 9 delete element_obj[i]; 10 download_count--; 11 } 12 } 13 }
3.滚动的时候触发事件,1000毫秒后执行lazy()方法。服务器
1 window.onscroll = window.onload = function () { 2 setTimeout(function () { 3 lazy(); 4 }, 1000) 5 }
整部分代码位于闭包自执行函数中。相应的方法放在init中。闭包
1 var lazyLoad = (function () { 2 function init() { 3 initElementMap(); 4 lazy(); 5 }; 6 return { 7 init: init 8 } 9 })();
使用格式 :src填默认loading图片地址,真实的图片地址填在lazy-src属性里,切记需指定宽高。在外部调用 lazyLoad.init();