懒加载的原理与实现

懒加载的原理

  • 原理:先将img标签中的src链接设为同一张图片(空白图片),将其真正的图片地址存储再img标签的自定义属性中(比如data-src)。当js监听到该图片元素进入可视窗口时,即将自定义属性中的地址存储到src属性中,达到懒加载的效果。
  • 这样做能防止页面一次性向服务器响应大量请求导致服务器响应慢,页面卡顿或崩溃等问题。

代码实现

  • 既然懒加载的原理是基于判断元素是否出现在窗口可视范围内,首先我们写一个函数判断元素是否出现在可视范围内:
function isVisible($node){
    var winH = $(window).height(),
        scrollTop = $(window).scrollTop(),
        offSetTop = $(window).offSet().top;
    if (offSetTop < winH + scrollTop) {
        return true;
    } else {
        return false;
    }
}
  • 再添加上浏览器的事件监听函数,让浏览器每次滚动就检查元素是否出现在窗口可视范围内:
$(window).on("scroll", function{
    if (isVisible($node)){
        console.log(true);
    }
})
  • 我们已经很接近了,现在我们要做的是,让元素只在第一次被检查到时打印true,之后就不再打印了
var hasShowed = false;
$(window).on("sroll",function{
    if (hasShowed) {
        return;
    } else {
        if (isVisible($node)) {
            console.log(true);
        }
    }
})

咦,我们好像已经实现了懒加载。 
下面是我的实现:

  • 展示代码
  • <!DOCTYPE html>
    <html>
    <head>
    	<script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.js
    "></script>
    	<title>demo lazyload</title>
    	<meta charset="utf-8">
    	<style type="text/css">
    		* {
    			padding: 0;
    			margin: 0;
    			text-decoration: none;
    			list-style: none;
    		}
    		.layout {
    			margin: 0 auto;
    			width: 1000px;
    		}
    		.lazyload img {
    			width: 300px;
    			height: 400px;
    		}
    		.img-ct {
    			margin-left: -50px;
    			overflow: auto;
    		}
    		.item {
    			float: left;
    			margin-left: 50px;
    			margin-bottom: 30px;
    		}
    	</style>
    </head>
    <body>
    <div class="lazyload">
      <div class="layout">
    	<ul class="img-ct">
    		<li class="item">
    			<a href="javascript:void(0)"><img data-img="img/Tsingtao.jpeg" src="img/blank.jpg"></a>
    		</li>
    		<li class="item">
    			<a href="javascript:void(0)"><img data-img="img/Tsingtao.jpeg" src="img/blank.jpg"></a>
    		</li>
    		<li class="item">
    			<a href="javascript:void(0)"><img data-img="img/Tsingtao.jpeg" src="img/blank.jpg"></a>
    		</li>
    		<li class="item">
    			<a href="javascript:void(0)"><img data-img="img/Tsingtao.jpeg" src="img/blank.jpg"></a>
    		</li>
    		<li class="item">
    			<a href="javascript:void(0)"><img data-img="img/Tsingtao.jpeg" src="img/blank.jpg"></a>
    		</li>
    		<li class="item">
    			<a href="javascript:void(0)"><img data-img="img/Tsingtao.jpeg" src="img/blank.jpg"></a>
    		</li>
    		<li class="item">
    			<a href="javascript:void(0)"><img data-img="img/Tsingtao.jpeg" src="img/blank.jpg"></a>
    		</li>
    		<li class="item">
    			<a href="javascript:void(0)"><img data-img="img/Tsingtao.jpeg" src="img/blank.jpg"></a>
    		</li>
    		<li class="item">
    			<a href="javascript:void(0)"><img data-img="img/Tsingtao.jpeg" src="img/blank.jpg"></a>
    		</li>
    		<li class="item">
    			<a href="javascript:void(0)"><img data-img="img/Tsingtao.jpeg" src="img/blank.jpg"></a>
    		</li>
    		<li class="item">
    			<a href="javascript:void(0)"><img data-img="img/Tsingtao.jpeg" src="img/blank.jpg"></a>
    		</li>
    		<li class="item">
    			<a href="javascript:void(0)"><img data-img="img/Tsingtao.jpeg" src="img/blank.jpg"></a>
    		</li>
    		<li class="item">
    			<a href="javascript:void(0)"><img data-img="img/Tsingtao.jpeg" src="img/blank.jpg"></a>
    		</li>
    		<li class="item">
    			<a href="javascript:void(0)"><img data-img="img/Tsingtao.jpeg" src="img/blank.jpg"></a>
    		</li>
    	</ul>
      </div>
    </div>
    
    
    <script type="text/javascript">
    var lazyLoad = (function(){
    	var clock;
    	
    	function init(){
    		$(window).on("scroll", function(){
    			if (clock) {
    				clearTimeout(clock);
    			}
    			clock = setTimeout(function(){
    				checkShow();
    			}, 200);
    		})
    		checkShow();
    	}
    	
    	function checkShow(){
    		$(".lazyload img").each(function(){
    			var $cur =$(this);
    			if($cur.attr('isLoaded')){
            		return;
          		}
    			if(shouldShow($cur)){
    				showImg($cur);
    			}
    		})
    	}
    	function shouldShow($node){
    		var scrollH = $(window).scrollTop(),
    			winH = $(window).height(),
    			top = $node.offset().top;
    		if(top < winH + scrollH){
    	  		return true;
    	  	}else{
    	  		return false;
    	  	}
    	}
    	function showImg($node){
        	$node.attr('src', $node.attr('data-img'));
        	$node.attr('isLoaded', true);
    	}
    	return {
    		init: init
    	}
    })()
    lazyLoad.init();
    </script>
    </body>
    </html>

     

无限滚动

利用懒加载和AJAX,我们还可以实现无限滚动查看时间线的效果,下面是我的实现: 
展示代码

<!DOCTYPE html>
<html>
<head>
<title>demo loadmore</title>
<meta charset="utf-8">
<script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.js
"></script>
<style type="text/css">
* {
text-align: center;
}
.box {
border: 1px solid #ccc;
padding: 10px;
margin: 10px;
}
.box:hover {
background-color: green;
}
.btn {
border: 1px solid #e27272;
border-radius: 2px;
color: #e27272;
padding: 10px;
margin: 10px;
display: inline-block;
cursor: pointer;
width: 64px;
height: 18px;
text-align: center;
}
.btn img {
width: 18px;
}
</style>
</head>
<body>
<div class="ct">
<div class="box">内容1</div>
<div class="box">内容2</div>
</div>
<a class="btn">加载更多</a>
<script type="text/javascript">
var $loadMoreBtn = $(".btn");
var clock;
loadMore($loadMoreBtn);
$(window).on("scroll", function(event){
if (clock) {
clearTimeout(clock);
}
clock = setTimeout(function(){
if (!isVisible($loadMoreBtn)) {
console.log(111);
return;
}
loadMore($loadMoreBtn);
},500);
})
function isVisible($node){
var offsetH = $node.offset().top;
var winH = $(window).height();
var scrollH = $(window).scrollTop();
if (offsetH < winH +scrollH) {
return true;
} else {
return false;
}
}
function loadMore($node){
var nowLength = $(".ct").children().size();
if($(this).data("isLoading")){
return;
}
$node.data("isLoading", true).html('<img src="loading.gif">');
$.ajax({
url: "demo3.php",
dataType: "json",
type: "get",
data: {
start: (nowLength+1),
len: 20
},
success: function(json){
onSuccess(json);
},
error: function(){
onError();
}
});
function onSuccess(json){
if (json.status === 1){
for(var i=0;i<json.data.length;i++){
$(".ct").append('<div class="box">' + json.data[i] + '</div>');
}
$node.data("isLoading", false).text("加载更多");
} else {
$node.data("isLoading", false).text('加载更多');
alert("加载失败,服务器原因");
}
}
function onError(){
$this.data("isLoading", false).text('加载更多');
alert("加载失败,网络原因");
}
};
</script>


</body>
</html>

回到顶部

利用懒加载的原理,我们还可以实现在滚动页面一段距离后,出现回到顶部按钮的这种效果,下面是我的实现 
展示代码
<!DOCTYPE html>
<html>
<head>
<title>demo gotop</title>
<meta charset="utf-8">
<style type="text/css">
.gotop li {
height: 50px;
line-height: 50px;
}
#go-top {
position: fixed;
bottom: 10px;
right: 10px;
border: 1px solid red;
padding: 10px;
cursor: pointer;
display: none;
}
</style>
</head>
<body>
<div class="gotop">
<li>内容1,我是顶部,我是顶部,我是顶部。</li>
<li>内容2</li>
<li>内容3</li>
<li>内容4</li>
<li>内容5</li>
<li>内容6</li>
<li>内容7</li>
<li>内容8</li>
<li>内容9</li>
<li>内容10</li>
<li>内容11</li>
<li>内容12</li>
<li>内容13</li>
<li>内容14</li>
<li>内容15</li>
<li>内容16</li>
<li>内容17</li>
<li>内容18</li>
<li>内容19</li>
<li>内容20</li>
<li>内容1</li>
<li>内容2</li>
<li>内容3</li>
<li>内容4</li>
<li>内容5</li>
<li>内容6</li>
<li>内容7</li>
<li>内容8</li>
<li>内容9</li>
<li>内容10</li>
<li>内容11</li>
<li>内容12</li>
<li>内容13</li>
<li>内容14</li>
<li>内容15</li>
<li>内容16</li>
<li>内容17</li>
<li>内容18</li>
<li>内容19</li>
<li>内容20</li>
</div>
<script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.js"></script>
<script type="text/javascript">
var goTop = (function(){
var $goTop = $('<div id="go-top">回到顶部</div>');
$("body").append($goTop);
function init(){
$(window).on("scroll", function(){
var offsetTop = $("body").scrollTop();
if (offsetTop > 100) {
$goTop.show();
} else {
$goTop.hide();
}
})
$goTop.on("click", function(){
$(window).scrollTop(0);
})
}
return {
init: init
}
})();
goTop.init();
</script>
</body>
</html>

发布了40 篇原创文章 · 获赞 18 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/yinxiangzhongqing/article/details/73740287