懒加载和瀑布流布局
简述图片懒加载的实现原理
原理:先将img标签中的src链接设为同一张图片(空白图片),将其真正的图片地址存储再img标签的自定义属性中(比如data-src)。当js监听到该图片元素进入可视窗口时,即将自定义属性中的地址存储到src属性中,达到懒加载的效果。
这样做能防止页面一次性向服务器响应大量请求导致服务器响应慢,页面卡顿或崩溃等问题。
简述瀑布流布局的实现原理
瀑布流布局由pinterest.com网站首创,它的原理是:先通过计算出一排能够容纳几列元素,然后寻找各列之中所有元素高度之和的最小者,并将新的元素添加到该列上,然后继续寻找所有列的各元素之和的最小者,继续添加至该列上,如此循环下去,直至所有元素均能够按要求排列为止;
简述木桶布局的实现原理(可选)
参考
高度一样,而宽度不同的布局方式称之为木桶布局。它有几个鲜明的特点: 每行的图片高度一致;每行的图片都是占满的。
采用构造函数创建对象的方式来写这段代码,注意按照约定构造函数的首字母要大写。创建一个新对象,然后将构造函数的作用域赋给新对象,调用构造函数中的方法。
函数名声明为 Barrel ,意为木桶。然后就要确定有哪些属性和方法。在理解了思路步骤的前提下,可以构思需要哪些属性、方法以及它们的作用。
属性:
每行图片的高度固定: rowHeight, 行高
拥有一个固定的容器: DOM对象,一个容器 命名为 .ct。 还应该有行容器和图片容器,但是由于这两个容器内容数量不固定,所以在布局的时候再创建
行容器的宽度: width, 获取ct的宽度
存放每行图片的数组: imgArr[]。每次把加载的图片压入该数组,判断该行是否超出宽度。
方法:
拥有素材图片 : 通过getImgUrls()方法来获取图片链接,(或从数据库中获取图片)。这里是通过访问https://placeholder.com/ 网站来获取代码,具体后述
加载图片信息: loadImg()方法来加载图片,以便获取图片信息,
渲染图片队列: render() 改变图片的比例大小,计算一行可以放置多少个图片
放置图片位置: layout() 将改变完大小的图片放置到页面上,append到对应的DOM元素节点上。具体关系对应前面的父子关系即可
如何判断元素出现在用户视野?
在用户的视野中有新的图片进入时才去判断
有两种情况:
(一)获取窗口、窗口滚动和元素距离窗口顶部的偏移高度,计算元素是否出现在窗口可视范 围内;
function isShow($el){
var winH = $(window).height(),//获取窗口高度
scrollH = $(window).scrollTop(),//获取窗口滚动高度
top = $el.offset().top;//获取元素距离窗口顶部偏移高度
if(top < scrollH + winH){
return true;//在可视范围
}else{
return false;//不在可视范围
}
}
(二)监听窗口滚动事件,检查元素是否在可视范围内;
$(window).on('scroll', function(){//监听滚动事件
checkShow();
})
checkShow();
function checkShow(){//检查元素是否在可视范围内
$('img').each(function(){//遍历每一个元素
var $cur = $(this);
if(!!isloaded($cur)){return;}//判断是否已加载
if (isShow($cur)) {
setTimeout(function(){
showImg($cur);
},300)//设置时间是为了更好的看出效果
};
});
}
(三)元素显示的时候把之前的默认照片替换成data-src里的照片。
function showImg($el){
$el.attr('src', $el.attr('data-src'));
$cur.data('isloaded',true);
}
如何判断浏览器滚动到最底部?
判断滚动条是否滚动到底部,需要用到DOM的三个属性值,
scrollTop为滚动条在Y轴上的滚动距离。
clientHeight为内容可视区域的高度。
scrollHeight为内容的总高度
//滚动条在Y轴上的滚动距离
function getScrollTop(){
var scrollTop = 0, bodyScrollTop = 0, documentScrollTop = 0;
if(document.body){
bodyScrollTop = document.body.scrollTop;
}
if(document.documentElement){
documentScrollTop = document.documentElement.scrollTop;
}
scrollTop = (bodyScrollTop - documentScrollTop > 0) ? bodyScrollTop : documentScrollTop;
return scrollTop;
}
//文档的总高度
function getScrollHeight(){
var scrollHeight = 0, bodyScrollHeight = 0, documentScrollHeight = 0;
if(document.body){
bodyScrollHeight = document.body.scrollHeight;
}
if(document.documentElement){
documentScrollHeight = document.documentElement.scrollHeight;
}
scrollHeight = (bodyScrollHeight - documentScrollHeight > 0) ? bodyScrollHeight : documentScrollHeight;
return scrollHeight;
}
//浏览器视口的高度
function getWindowHeight(){
var windowHeight = 0;
if(document.compatMode == "CSS1Compat"){
windowHeight = document.documentElement.clientHeight;
}else{
windowHeight = document.body.clientHeight;
}
return windowHeight;
}
function touchedBottom(){
if(getScrollTop() + getWindowHeight() == getScrollHeight()){
console.log("you are in the bottom!");
return true;
}else{
return false;
}
};
实现课程中的图片懒加载效果
git预览:https://ouyangbeibei.github.io/project/layout.md/lazyLoad.md/lazyLoad.html
实现课程中瀑布流布局效果
jsbin预览:http://jsbin.com/dicafopefu/edit?html,output
实现瀑布流新闻网站,回复 GitHub 项目地址和项目预览链接
查看效果
任务要求:
- 在 Github 建一个项目 waterfall-sinanews
- 项目结构
jsbin预览:http://jsbin.com/ruguwuvomo/edit?html,output
git代码地址:https://github.com/ouyangbeibei/project/tree/master/layout.md/waterfall-sinanews.md