懒加载的原理
- 原理:先将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>