一、懒加载
1.什么是懒加载
目前,网络上各大论坛,尤其是一些图片类型的网站上,在图片加载时均采用了一种名为懒加载的方式,具体表现为,当页面被请求时,只加载可视区域的图片,其它部分的图片则不加载,只有这些图片出现在可视区域时才会动态加载这些图片,从而节约了网络带宽和提高了初次加载的速度。
2.懒加载的原理
页面中的img元素,如果没有src属性,浏览器就不会发出请求去下载图片,只有通过javascript设置了图片路径,浏览器才会发送请求。
懒加载的原理就是先在页面中把所有的图片统一使用一张占位图进行占位,把正真的路径存在元素的自定义属性“data-src”(这个名字起个自己认识好记的就行)里,要用的时候就取出来,把它的值赋值给img的src属性。
二、获取屏幕高度:jquery的height()和javascript的height
1、jquery的各种高度
首先来说一说$(document)和$(window),如下:
$(document).height();//整个网页的高度
$(window).height();//浏览器可视窗口的高度
$(window).scrollTop();//浏览器可视窗口顶端距离网页顶端的高度(垂直偏移)
用一句话理解就是:当网页滚动条拉到最低端时,
$(document).height() == $(window).height() + $(window).scrollTop()
注意,是拉到最低端!
当网页高度不足浏览器窗口时$(document).height()
返回的是$(window).height()
假如您要获取整个网页的高度,不建议用$("html").height()
、$("body").height()
的高度,
原因:
$("body").height()
:body可能会有边框,获取的高度会比$(document).height()
小; $("html").height()
:在不同的浏览器上获取的高度的意义会有差异,说白了就是浏览器不兼容。
说道这里,提及边框和margin还有padding,我们自然想到了jquery的另外的两个高度,那就是innerHeight()
和outerHeight()
innerHeight()
和outerHeight()
不适用于window 和 document对象,对于window 和 document对象可以使用.height()
代替。innerHeight()
和outerHeight()
主要用来获取标签的高度。
在jQuery中,获取元素高度的函数有3个,它们分别是height()、 innerHeight()、 outerHeight()。
与此相对应的是,获取元素宽度的函数也有3个,它们分别是width()、 innerWidth()、 outerWidth()。这三个函数获取的是元素的高度,而不是元素到页面顶部的高度,要获取元素到页面顶部的高度可以用offset().top
。
以height()、innerHeight()、outerHeight()3个函数为例,来详细介绍它们之间的区别。
下面以元素element的盒模型为例来介绍它们之间的区别。
只有height()函数可用于window或document对象。
"支持写操作"表示该函数可以为元素设置高度值。
1.4.1+ height()新增支持参数为函数(之前只支持数值)。
1.8.0+ innerHeight()支持参数为数值或函数。
jquery高度,放到浏览器中试一下
alert($(window).height()); //浏览器当前窗口可视区域高度
alert($(document).height()); //浏览器当前窗口文档的高度
alert($(document.body).height()); //浏览器当前窗口文档body的高度
alert($(document.body).outerHeight(true)); //浏览器当前窗口文档body的总高度 包括border padding margin
alert($(window).width()); //浏览器当前窗口可视区域宽度
alert($(document).width()); //浏览器当前窗口文档对象宽度
alert($(document.body).width()); //浏览器当前窗口文档body的宽度
alert($(document.body).outerWidth(true)); //浏览器当前窗口文档body的总宽度 包括border padding margin
javascript的各种高度
网页可见区域宽[仅针对body]: document.body.clientWidth
网页可见区域高[仅针对body]: document.body.clientHeight
网页可见区域宽[仅针对body]: document.body.offsetWidth (包括滚动条和边框,若滚动条和边框为0,则和clientWidth相等)
网页可见区域高[仅针对body]: document.body.offsetHeight (包括滚动条和边框,若滚动条和边框为0,则和clientHeight相等)
可视窗口宽度(包括滚动轴宽度):window.innerWidth; //IE9+、Chrome、Firefox、Opera 以及 Safari
可视窗口高度,不包括浏览器顶部工具栏: window.innerHeight;//IE9+、Chrome、Firefox、Opera 以及 Safari
网页正文全文宽(不包括滚动轴的宽度): document.body.scrollWidth
网页正文全文高:document.body.scrollHeight
//假如网页中没有滚动轴,document.body.scrollWidth和window.innerWidth相等,document.body.scrollHeight和window.innerHeight相等。
获取滚动条的滚动高度值:document.documentElement.scrollTop
获取滚动条的滚动高度值: document.body.scrollTop
获取滚动条的滚动宽度值: document.body.scrollLeft
网页正文部分上: window.screenTop
网页正文部分左: window.screenLeft
屏幕分辨率的高(整个屏幕的高度): window.screen.height
屏幕分辨率的宽(整个屏幕的宽度): window.screen.width
屏幕可用工作区高度: window.screen.availHeight
屏幕可用工作区宽度: window.screen.availWidth
整个浏览器可用工作区高度: window.outerHeight
整个浏览器可用工作区宽度: window.outerWidth
获取scrollTop兼容各浏览器的方法,以及body和documentElement是啥?
三、如何判断一个元素是否出现在窗口可视范围(浏览器的上边缘和下边缘之间,肉眼可视)。写出一个函数isVisible实现
function isVisible($img){
//获取浏览器窗口高度
var windowHeight = $(window).height(),
//获取窗口滚动的高度
windowScrolltop = $(window).scrollTop(),
//获取图片到页面顶部的高度
imgOffsettop = $img.offset().top,
//获取图片元素自己的高度,包括内外边距
imgHeight = $img.outerHeight(true);
if(windowHeight + windowScrolltop > imgOffsettop && imgOffsettop + imgHeight > windowScrolltop){
return true
}
return false
}
四、当窗口滚动时,判断一个元素是不是出现在窗口可视范围。每次出现都在控制台打印 true 。用代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
body{
background: pink;
padding: 30px;
height: 1800px;
}
#hello{
position: absolute;
top: 1200px;
left: 40%;
padding: 50px;
border: 2px solid red;
background: yellow;
}
</style>
</head>
<body>
<p id="hello">hello</p>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script>
$(window).on('scroll',function result(){
if(isVisible($('#hello'))){
console.log(true);
}
else{
console.log(false);
}
})
function isVisible($img){
var windowHeight = $(window).height(),
windowScrolltop = $(window).scrollTop(),
imgoffsetTop = $img.offset().top,
imgHeight = $img.outerHeight(true);
if(windowHeight + windowScrolltop > imgoffsetTop && windowScrolltop < imgoffsetTop + imgHeight ){
return true;
}
else {
return false;
}
}
</script>
</body>
</html>
五、当窗口滚动时,判断一个元素是不是出现在窗口可视范围。在元素第一次出现时在控制台打印 true,以后再次出现不做任何处理。用代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
body{
background: pink;
padding: 30px;
height: 1800px;
}
.p{
position: absolute;
top: 1200px;
left: 40%;
padding: 50px;
border: 2px solid red;
background: yellow;
}
</style>
</head>
<body>
<p class="p">hello</p>
<script src="https://cdn.bootcss.com/jquery/1.9.1/jquery.js"></script>
<script>
var isShow=false;
$(window).on('scroll',function result(){
if(!isShow && isVisible($('.p'))){
console.log(true);
}
})
function isVisible($img){
var windowHeight = $(window).height(),
windowScrolltop = $(window).scrollTop(),
imgoffsetTop = $img.offset().top,
imgHeight = $img.outerHeight(true);
if(windowHeight + windowScrolltop > imgoffsetTop && windowScrolltop < imgoffsetTop + imgHeight ){
isShow=true;
return true;
}
return false;
}
</script>
</body>
</html>
6、使用jQuery实现懒加载
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
ul,li{
list-style:none;
}
.container{
width: 600px;
margin: 0 auto;
}
.container li{
float: left;
margin: 10px 10px;
}
.container li img{
width: 240px;
height: 180px;
}
</style>
</head>
<body>
<ul class="container clearfix">
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
<li><a href="">![](http://upload-images.jianshu.io/upload_images/1969310-00fe161fe69693cf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
</ul>
<script src="https://cdn.bootcss.com/jquery/1.9.1/jquery.js"></script>
<script>
/*
大体思路:
1.对于所有的img标签,把真实的地址放入自定义属性data-img
2.当滚动页面时,检查页面所有的img标签,看看这个标签是否出现到我们的视野,当出现在我们的视野时
再去判断它是否已经加载过,如果没有加载,加载它
*/
// 用户第一次打开页面,还未滚动窗口的时候需要执行一次 lazyRender
lazyRender();
var clock;
$(window).on('scroll',function(){
//用户鼠标滚轮滚动一次,有多次事件响应。下面的 setTimeout 主要是为性能考虑,只在最后一次事件响应的时候执行 lazyRender,若在300毫秒内再次滚动则清除原来的定时器
if(clock){
clearTimeout(clock)
}
clock = setTimeout(function(){
lazyRender();
}, 300)
})
function lazyRender() {
$('.container img').each(function(){
//判断图片是否出现在可视窗口和图片是否已经加载
if( checkShow($(this)) && !isLoaded($(this)) ){
//若图片出现在可是区域且没有加载,加载图片
loadImg($(this))
}
})
}
//判断图片出没出现在可视窗口
function checkShow($img) {
//获取浏览器窗口高度
var windowHeight = $(window).height(),
//获取窗口滚动的高度
windowScrolltop = $(window).scrollTop(),
//获取图片到页面顶部的高度
imgOffsettop = $img.offset().top,
//获取图片元素自己的高度,包括内外边距
imgHeight = $img.outerHeight(true);
if(windowHeight + windowScrolltop > imgOffsettop && imgOffsettop + imgHeight > windowScrolltop){
return true
}
return false
}
//判断图片加没加载过
function isLoaded($img) {
return $img.attr('data-src') === $img.attr('src')
}
//加载图片
function loadImg($img) {
$img.attr('src',$img.attr('data-src'))
}
</script>
</body>
</html>