瀑布流+懒加载
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了瀑布流+懒加载相关的知识,希望对你有一定的参考价值。
参考技术A 你们是否见过漂亮的照片墙呢?对,就是那种照片大小不一,看似不整齐但却有一定的排版,反而让人有一种赏阅感。其实在这美妙的背后,想要做一个照片墙出来,还需要用到懒加载。那有伙伴可能就要问了,什么是懒加载,你之前也没提到过呀,是的我确实没有讲过,但是哈我有说过预加载,懒加载无非就是一次性加载的照片多一点而已,让图片在可视区加载,即仅加载可以看到的区域,监控滚动条实现,设置超过一定值时又加载图片,相比较预加载,懒加载可以优化前端性能,减少请求数或延迟请求数,减少服务器的压力,那么接下来就由我来说说吧。深度剖析-class的几个对象(utlis,component)-瀑布流-懒加载(概念,作用,原理,实现步骤)
💦正因为生命有限,所以才显得更重要,正因为生命有限,所以才更应该努力不懈。💦
深度剖析
深度剖析-class的几个对象-瀑布流-懒加载-面向对象实现(多选按钮-单选按钮)
分析class的几个对象-瀑布流-懒加载-多选框-单选框
深度剖析component.js:组件类的功能
export default class Component
/* 一个实例属性 */
elem;
/* 传入一个HTML类型 */
constructor(type)
/* 创建一个htmlElement */
this.elem = document.createElement(type);
this.elem.className = 'div1';
this.elem.innerHTML = '我爱你'
// document.body.appendChild(this.elem)
/* 传入一个父容器标签名字字符串,将创造的htmlElement添加在父容器里之后 */
appendTo(parent)
/* 判断字符串,获取其对应的元素对象 */
if (typeof parent === 'string') parent = document.querySelector(parent)
/* 给父元素对象后appendChild(实例属性) */
parent.appendChild(this.elem);
/* 并且返回这个父容器 */
return parent;
/* 实例方法,将创造的属性对象,插入某个父容器的document对象之前 */
insertTo(parent, nextElement)
/* 判断其类型是否Wie字符串 ,获取其document对象*/
if (typeof parent === 'string') parent = document.querySelector(parent);
if (typeof nextElement === 'string') nextElement = document.querySelector(nextElement);
/* 如果条件符合,将数据插入到nextElement之前 */
if (parent instanceof HTMLElement && nextElement instanceof HTMLElement)
parent.insertBefore(this.elem, nextElement);
深度剖析Utils.js:设置样式和创建元素
/* 静态方法类名调用 */
export default class Utils
constructor()
/* 构造函数可以默认为空,实例化对象时不执行任何代码 */
/* 传入一个css样式的代码字符串 */
static setCSS(css)
/*
document.styleSheets.length 代表的是style样式的个数
Array.from(document.styleSheets) 将多个style转为数组处理
![].some(item => item.ownerNode.id === 'defined') 寻找style样式的id属性中是否有一个defined
*/
/* 如果啥都没有,style上面也没有id默认值 */
if (document.styleSheets.length == 0 || !Array.from(document.styleSheets).some(item => item.ownerNode.id === 'defined'))
/* 创建一个style标签 */
var style = document.createElement('style');
/* 将传进来的css字符串添加到style中 */
style.innerHTML = css;
/* 并给这个样式添加一个鉴别值 */
style.id = 'defined';
/* 并且将style标签添加入到hand中 */
document.head.appendChild(style);
return;
/* 如果有一个样式的id默认值是:defined 找出这个样式*/
var styleSheet = Array.from(document.styleSheets).find(item => item.ownerNode.id === 'defined')
/* 将传进来的css字符串解析 按最后的分割,然后去掉空格,每一个样式通过数组来调用*/
var arr = css.split(/(?<=\\)/).map(item => item.trim());
/* 然后遍历数组添加这个将每一个css样式添加进去 */
arr.forEach(item =>
styleSheet.insertRule(item, styleSheet.cssRules.length)
)
/* 下面这块作为扩展看看就行,创建一个元素并返回,并插入到这个父容器里面 */
static createElement(type, className, parent)
if (typeof parent === 'string') parent = document.querySelector(parent);
var elem = document.createElement(type);
if (className) elem.className = className;
if (parent instanceof HTMLElement) parent.appendChild(elem)
return elem;
瀑布流
💚瀑布流又称瀑布流式布局,是比较流行的一种网站页面布局方式。视觉表现为参差不齐的多栏布局。
- 实现逻辑:
每次选择每列高度最低的一列插入图片
- 这个思路需要注意几点:ul作为最外层的容器,宽度的设置
Wie100%;list-style: none;
- li需要float起来
- 最后记得清除浮动
清除浮动常用样式
.clear::after
content: "";
display: block;
visibility: hidden;
height: 0;
overflow: hidden;
clear: both;
- 第一步初始化,根据需求创建列数;查看是否渲染到页面
- 第二步,作为图片加载,添加load事件,加载成功之后获取相应height
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
ul
width: 100%;
margin: 0;
padding: 0;
list-style: none;
li
float: left;
margin: 0;
li img
width: 98%;
.clear::after
content: "";
display: block;
visibility: hidden;
height: 0;
overflow: hidden;
clear: both;
</style>
</head>
<body>
<ul class="clear"></ul>
<!-- 设置外层盒子并且选择好样式 -->
<script>
const COL = 5;/* 设置为5列显示 */
var ul;
var i=2;
init();
/* 初始化 */
function init()
/* 获取ul对象,根据需求添加元素 */
ul = document.querySelector('ul')
/* 添加li条 根据需求可调整列数*/
ul.innerHTML = Array(COL).fill(1).reduce(v=> v+`<li style='width:$100/COL%'></li>`,"");
/* 执行图片加载 */
loadImage(i);
/* 加载图片 */
function loadImage(i)
var img = new Image();
img.src = `./img/load/$i-.jpg`;
/* 给img添加加载事件 */
img.addEventListener("load",loadHandler);
function loadHandler(e)
/* 提示:注意的是这里的this,指的就是img对象 */
/* 加载完之后执行次函数,卸载加载侦听 */
this.removeEventListener("load",loadHandler);
/*t.offsetHeight:每一个ul的子元素, ul.firstElementChild.offsetHeight:ul的第一个子元素 */
/* 找出li最小的 Height 值*/
var min = Array.from(ul.children).reduce((v,t)=>t.offsetHeight<v?t.offsetHeight :v,ul.firstElementChild.offsetHeight);
/* 找出那个最小min的li */
var li = Array.from(ul.children).find(t=>t.offsetHeight === min);
/* 将this对象插入 */
li.appendChild(this);
/* 在这里就已经完成了一张图片的插入,现在考虑这个加载停止和继续加载 */
/* ================================== */
/* 变换i值 */
i++;
/* 如果超过79就停止执行 */
if(i>79) return
/*
* 页面中的img元素,如果没有src属性,浏览器就不会发出请求去下载图片
* 只有通过javascript设置了图片路径,浏览器才会发送请求。
* 继续执行加载函数
*/
loadImage(i);
</script>
</body>
</html>
懒加载
JavaScript中的懒加载——概念,作用,原理,实现步骤
- 什么是懒加载?
- 懒加载也就是延迟(控制开关)加载。
- 针对本案例的:我自己的理解就是当我的加载区域达到某个条件,触发开关,关闭图片加载,当通过滚动条对达到某一条件,又继续开始加载。这就是懒加载
当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成一张大小为1*1px图片的路径(这样就只需请求一次,俗称占位图),以后再理解可能情景不同只有当图片出现在浏览器的可视区域内时,才设置图片正真的路径,让图片显示出来。这就是图片懒加载。
- 为什么要使用懒加载?
很多页面,内容很丰富,页面很长,图片较多,例如瀑布流。比如说各种商城页面。这些页面图片数量多,而且比较大,少说百来K,多则上兆。
要是页面载入就一次性加载完毕。估计大家都会等到黄花变成黄花菜了。
- 懒加载的原理是什么?
- 页面中的img元素,如果没有src属性,浏览器就不会发出请求去加载图片, 只有通过javascript设置了(改变了)图片路径,浏览器才会发送请求。
- 第一种是纯粹的延迟加载,使用setTimeOut或setInterval进行加载延迟
- 第二种是条件加载,符合某些条件,或触发了某些事件才开始异步加载。
- 第三种是可视区加载,即仅加载用户可以看到的区域,这个主要由监控滚动条来实现,一般会在距用户看到某图片前一定距离遍开始加载,这样能保证用户拉下时正好能看到图片。
- 懒加载的实现步骤?
此案例就是对条件判断。
ul
的高度大于当前视口高度的4倍+当前滚动条已过去的高度
5.懒加载的优点是什么?
页面加载速度快、可以减轻服务器的压力、节约了流量,用户体验好
6:懒加载代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
ul
width: 100%;
margin: 0;
padding: 0;
list-style: none;
li
float: left;
margin: 0;
li img
width: 98%;
.clear::after
content: "";
display: block;
visibility: hidden;
height: 0;
overflow: hidden;
clear: both;
</style>
</head>
<body>
<ul class="clear"></ul>
<!-- 设置外层盒子并且选择好样式 -->
<script>
const COL = 5;/* 设置为5列显示 */
var ul;
var i=2;
init();
/* 初始化 */
function init()
/* 获取ul对象,根据需求添加元素 */
ul = document.querySelector('ul')
/* 添加li条 根据需求可调整列数*/
ul.innerHTML = Array(COL).fill(1).reduce(v=> v+`<li style='width:$100/COL%'></li>`,"");
/* 执行图片加载 */
loadImage(i);
/* 添加滚轮事件,后面判断滚轮位置 */
window.addEventListener('scroll',scrollHandler)
/* 加载图片 */
function loadImage(i)
var img = new Image();
img.src = `./img/load/$i-.jpg`;
/* 给img添加加载事件 */
img.addEventListener("load",loadHandler);
function loadHandler(e)
/* 提示:注意的是这里的this,指的就是img对象 */
/* 加载完之后执行次函数,卸载加载侦听 */
this.removeEventListener("load",loadHandler);
/*t.offsetHeight:每一个ul的子元素, ul.firstElementChild.offsetHeight:ul的第一个子元素 */
/* 找出li最小的 Height 值*/
var min = Array.from(ul.children).reduce((v,t)=>t.offsetHeight<v?t.offsetHeight :v,ul.firstElementChild.offsetHeight);
/* 找出那个最小min的li */
var li = Array.from(ul.children).find(t=>t.offsetHeight === min);
/* 将this对象插入 */
li.appendChild(this);
/* 在这里就已经完成了一张图片的插入,现在考虑这个加载停止和继续加载 */
/* ================================== */
// ul的高度大于当前视口高度的4倍+当前滚动条已过去的高度
if(ul.offsetHeight>document.documentElement.clientHeight*4+document.documentElement.scrollTop) return;
continueLoad();
/* 滚轮事件函数 */
function scrollHandler(e)
// 当前滚动条+视口高度的2倍大于ul的高度时,比较下面还留有1视口高度时继续加载
if(document.documentElement.scrollTop+document.documentElement.clientHeight*2>ul.offsetHeight)
continueLoad()
/* 函数化编程 */
function continueLoad()
i++;
if(i>79) i=2;
loadImage(i);
</script>
</body>
</html>
以上是关于瀑布流+懒加载的主要内容,如果未能解决你的问题,请参考以下文章