【javascript】图片懒加载的原生实现

背景

  • 这个题目面试应该比较常见,写的时候才发现这里面还有点算法。

思路

  • 图片懒加载就是src里全放同样的,等满足条件再把其属性上真实的src地址放到src上。

重要api

document.documentElement.clientWidth  可见区域宽度  
document.documentElement.clientHeight  可见区域高度  ###重要###
window.scrollY  纵向滑块滚了多少   ###重要###
window.scrollX   横向滑块滚了多少

body对象可视区宽度  document.body.clientWidth  
body对象可视区高度    document.body.clientHeight  ##重要##
body对象包括边线宽: document.body.offsetWidth (包括边线的宽)  
body对象包括边线高: document.body.offsetHeight (包括边线的高)  
body对象内容宽度: document.body.scrollWidth  
body对象内容高度: document.body.scrollHeight  
被卷去的高: document.body.scrollTop  									
被卷去的左: document.body.scrollLeft  
浏览器顶端到屏幕顶端距离: window.screenTop  	
浏览器左到屏幕左距离: window.screenLeft  
屏幕分辨率的高: window.screen.height  
屏幕分辨率的宽: window.screen.width  
屏幕可用工作区高度: window.screen.availHeight  (这个跟分辨率区别是减去了windows底部工具栏或者mac顶部菜单栏)
屏幕可用工作区宽度: window.screen.availWidth  
  
  • 一般考虑兼容性会写document.documentElement.clientxxx||document.body.clientxxxx

代码

  • 本次图片链接随便在网上翻的,有些看不见了,不过不影响代码逻辑。
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>Document</title>
</head>
<style>
.container{
	width: 800px;
	margin: 0 auto;
	display: flex;
	flex-direction: column;
}
.container img{
	justify-content: center;
	align-items: center;
	height: 800px;
	margin-bottom: 10px;
}
</style>
<body>
	<div class="container">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img4.imgtn.bdimg.com/it/u=951914923,777131061&fm=26&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img1.imgtn.bdimg.com/it/u=637435809,3242058940&fm=26&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img1.imgtn.bdimg.com/it/u=3990342075,2367006974&fm=200&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img1.imgtn.bdimg.com/it/u=1813891576,1754763093&fm=26&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img4.imgtn.bdimg.com/it/u=2539922263,2810970709&fm=200&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img4.imgtn.bdimg.com/it/u=1878067600,3935137756&fm=200&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img3.imgtn.bdimg.com/it/u=85690711,3884201894&fm=26&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img2.imgtn.bdimg.com/it/u=3844233833,3942617167&fm=200&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img0.imgtn.bdimg.com/it/u=1846695025,2515725663&fm=26&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img3.imgtn.bdimg.com/it/u=346230831,1833217134&fm=200&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img5.imgtn.bdimg.com/it/u=3478148120,2683867435&fm=26&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img5.imgtn.bdimg.com/it/u=2298824648,1812234339&fm=200&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img2.imgtn.bdimg.com/it/u=4201594846,4178139206&fm=26&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img2.imgtn.bdimg.com/it/u=484389598,819397330&fm=200&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img1.imgtn.bdimg.com/it/u=3729466012,914166979&fm=26&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img2.imgtn.bdimg.com/it/u=354463615,3836278171&fm=200&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img5.imgtn.bdimg.com/it/u=1831250492,3489827059&fm=200&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img1.imgtn.bdimg.com/it/u=779005622,2247570143&fm=200&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img1.imgtn.bdimg.com/it/u=1968229118,3512711019&fm=26&gp=0.jpg">
        <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img2.imgtn.bdimg.com/it/u=1088428253,1150170159&fm=200&gp=0.jpg">
    </div>
	<script>
	//滚动事件
	window.onscroll=debounce(mylazy,1000)
	function debounce(fn,wait){
		let timer=null
		return function(...args){
			let that = this
			clearTimeout(timer)
			timer = setTimeout(() => {
				fn.apply(that,args)
			}, wait);
		}
	}
	function mylazy(){
		//划定可视区域 
		let viewHeight = document.documentElement.clientHeight
		//获取滚动高度
		let scroll = window.scrollY
		let viewBottom = scroll+viewHeight
		//获取图片位置  top在可视区域或者底部在可视区域就进行赋值
		let container=document.querySelector(".container")
		let imgs = container.children
		//获取视口内imgs宽高 //这里用推算 所有图片大小相等
		let marginBottom = getComputedStyle(imgs[0],null).marginBottom
		let imgH = imgs[0].offsetHeight+Number(marginBottom.slice(0,-2))
		//第一张0-810 第n张*n 20-2000  头整除 尾不能整除加1
		let index1 =Math.floor(scroll/imgH)
		let index2 =Math.floor(viewBottom/imgH)+1
		//index2有越界可能
		index2 = index2>imgs.length?imgs.length:index2
		//赋值src
		for(let i =index1;i<index2;i++){
			let src = imgs[i].getAttribute("data-src")
			imgs[i].setAttribute("src",src)
		}
	}
	mylazy()//首次触发显示图片
	</script>
</body>
</html>
  • 再来个jquery实现的:
	jQuery.yehuo={
		mylazy:function(imgs,tag){
			let imgH = $(imgs[0]).outerHeight(true)
			let viewHeight= $(window).height();
			let scroll = $(window).scrollTop()
			let viewBottom = scroll+viewHeight
			let index1 = Math.floor(scroll/imgH)
			let index2 = Math.floor(viewBottom/imgH)+1
			index2=index2>imgs.length?img.length:index2
			console.log(index1,index2);
			for(let i =index1;i<index2;i++){
				let img = $(imgs[i])
				img.attr('src',img.attr(tag))
			}
		}
	}
	function debounce(fn,wait){
		let timer=null
		return function(...args){
			let that = this
			clearTimeout(timer)
			timer = setTimeout(() => {
				fn.apply(that,args)
			}, wait);
		}
	}
	let imgs = $('.container').children()
	$.yehuo.mylazy(imgs,'data-src')
	function wrap(){
		$.yehuo.mylazy(imgs,'data-src')
	}
	window.onscroll=debounce(wrap,1000)
  • 另外可以发现jq获取边距实在太容易了,直接outerHeight(),原生获取边距需要先拿到css属性,然后还要把px给截掉才行。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

业火之理

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值