原生JS实现懒加载与函数节流方法

先写下标题,今晚写这个博客~

昨晚改项目BUG改的太晚了,实在没空写,只能放在今天写咯~

最近写的小项目正好遇到需要懒加载和函数节流,查了资料了解了一下原理。现在写个博客总结一下查找到的资料并简单用JS实现一下,以便以后查阅~
注:本文未没有介绍预加载与函数防抖,主要是暂时未遇上这两个需求,日后有机会再补充!

懒加载

什么是懒加载呢?

  • 懒加载又称作延迟加载(英语:lazyload),通俗的说一下就是访问一个网页的时候,先把图片的路径换成固定的一张图让其先占好位置(即占位图)。当页面滚动到这张图片出现在页面可视区域内时立即设置图片的真实路径,这便是懒加载。

为什么要用懒加载呢?

  • 简单来说是为了优化网页,加快网页载入速度。说具体一点呢就是页面里的内容实在太多了,比如随便打开淘宝、京东等网上商城的网页,页面往下滚你可以看到有非常多的图片,这些图片大小不一,有的几百k有的可能要1m了。如果当用户进入页面时将这些图片全部都展示出来,那可能耗时太长,用户等的黄花菜都凉了。。。
  • 所以可以使用懒加载先展示在浏览器可视区域内的图片,加快页面载入速度~

那接下来我就简单用JS实现一下懒加载,代码如下:

// 先给页面内所有需要懒加载的图片赋予'lazyload'的类属性
// 然后把图片正确的地址放在'data-src'属性中,如<img data-src="http://xxx.jpg">
let images = document.querySelectorAll('.lazyload') // 查找所有包含lazyload类属性的标签
let imgs = [].slice.call(images) // images是一个伪数组(对象),将images转为真的数组
// let imgs = Arrary.from(images) 功能与上面一样,为ES6语法
let onscroll = function(){
  if(imgs.length === 0){ return window.removeEventListener('scroll', onscroll)}
  // 判断imgs这个数组是否为空,如果为空就代表页面内没有需要懒加载的图片,删除监听滚动的事件
  imgs.filter( (img)=> { img.classList.contains('lazyload') })
  // 过滤掉imgs数组中不包含类名为'lazyload'的标签
  imgs.forEach((img)=>{
    if(inViewport(img)){
      loadImage(img) // 如果此图片出现在视口内就设置图片的真实路径
    }
  })
}
window.addEventListener('scroll', onscroll) // 监听滚动事件,当滚动时触发onscroll
window.dispatchEvent(new Event('scroll'))
// 这行代码作用是让浏览器自动执行一下滚动事件,因为如果载入页面时浏览器自动没有执行滚动事件,那么此时在视口内的图片都没有真实的图片地址

function inViewport(img){
  let { top, left, bottom, right } = img.getBoundingClientRect()
  // 调用getBoundingClientRect()这个API,读取当前图片上下左右各边距离视口顶部和视口左边的值,并赋值给相应变量(这里使用的是ES6语法)
  let vpHeight = document.documentElement.clientHeight // 获取视口高度
  let vpWidth = document.documentElement.clientWidth // 获取视口宽度
  return (( top > 0 && top < vpHeight || bottom > 0 && bottom < vpHeight ) && 
  (left > 0 && left < vpWidth || right > 0 && right < vpWidth ))
  // 这行代码返回布尔值,图片在视口内返回true,不在视口内返回false
}

function loadImage(img){
  let image = new Image()
  // 创建一个image对象
  image.src = img.dataset.src
  // 读取img的'data-src'属性,将图片真实地址赋给image的src属性,相当于给浏览器缓存了这张真实的图片
  image.onload = function(){
    img.src = image.src
   // 当浏览器加载缓存的图片时,将图片真实地址放到此img标签内,那此img标签的真实图片便可直接展示出来
    img.classList.remove('lazyload') // 删除img标签的'lazyload'类属性
  }
}

函数节流

什么是函数节流呢?

  • 这里先说一下什么是节流:比如你家的水龙头开到最大档,那水龙头里的水会哗哗的流下来,但是如果你把水龙头拧紧直到水以水滴的形式流出,那你就会发现每隔一段时间才会有一滴水流出
  • 函数节流(英语:throttle)也就是设定一个执行的周期,前一次调用动作到当前调用动作的时间间隔大于或等于设定的执行周期时就执行该动作(如果时间间隔小于设定的执行周期时,就等时间到达设定的执行周期再执行动作),然后进入下一个周期。

为什么要用函数节流呢?

  • 主要是为了限制函数的执行频率,用于优化函数触发频率过高而导致响应速度跟不上触发频率,出现bug、延迟、卡顿等现象。

那接下来我就简单用JS实现一下函数节流,代码如下:

function throttle(func, wait){
// 设置一个名为throttle的函数,此函数可接受两个参数,一个参数为执行函数,另一个参数为执行周期
  let prev, timer
  // 声明两个变量,一个为前一次调用动作的时间,一个为计时器
  return function fn(){
  // 返回名为'fn'的函数
    let curr = Date.now()
    // 获取当前时间
    let diff = curr - prev
    // 获取前一次调用动作到当前调用动作的时间间隔
    if(!prev || diff >= wait){
      func()
      // 如果调是第一次用动作或时间间隔大于等于执行周期,则执行所传入的函数
      prev = curr // 将当前时间赋值给前一次调用动作的时间
    }else if(diff < wait){
      clearTimeout(timer) // 如果时间间隔小于执行周期(即在时间间隔内又触发了一次事件),就清空原先的定时器
      timer = setTimeout(fn, wait - diff) // 设置一个新的定时器,等时间到达设定的执行周期再执行函数'fn'
    }
  }
}

结语:以上就是我根据查找的资料总结实现的懒加载与函数节流。如果其中有问题,麻烦在评论中指出。谢谢~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容