原生JavaScript实现图片瀑布流效果,可更改配置参数 带完整版解析代码[waterFall.js]
2021-01-28 07:13
标签:改变 mamicode font osi var 定义 new sele fill ????????本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小生感激不尽。 ????????本篇文章为您分析一下原生JS实现图片瀑布流效果
整完!!! 原生JavaScript实现图片瀑布流效果,可更改配置参数 带完整版解析代码[waterFall.js] 标签:改变 mamicode font osi var 定义 new sele fill 原文地址:https://www.cnblogs.com/tewutuyo/p/12839975.html前言:
页面需求
1. 图片之前拥有最小间隙
2. 图片可以根据浏览器窗口的改变而改变
3. 需要用到函数节流与函数防抖的知识
HTML结构
CSS 样式
无
JS 行为
JS大致思路
1. 根据用户传入的配置信息设置图片信息
2. 配置默认值
3. 设置页面的图片
4. 设置父级元素的定位信息
5. 设置每张图片的left、top值
.计算一行有几张图片
定义一个数组,这个数组用来记录每一列下一张的top值
初始值为[0,0,0,n...]; 数组的每一项为0
. 设置图片位置时
(1).得到数组中最小的值,设置top
(2).更新数组中该项的top值
(3).得到该项是数组中的第几项,用于计算该项的left值
5. 获得水平方向上的距离信息(一行排几张图、最小间隙)
6. 设置图片的left、top值
/**
* 第一步: 创建一个图片瀑布流
* @param {*} option 参数配置
*/
window.myPlugin.createWaterFall = function (option) {
// option默认值
var defaultOption = {
minGap: 10, // 图片最小间隙
imgSrcs: [], // 图片的路径数组
imgWidth: 220, // 单张图片的宽度
container: document.body // 需要渲染的容器,如果用户没有传,默认为body
}
// 第二步: 对象混合
var option = Object.assign({}, defaultOption, option);
// console.log(option);
var imgs = []; // 存放所有的图片dom对象。
}
createImg();
// setFatherPosition();
/**
* 第三步: 创建图片
*/
function createImg() {
for (var i = 0; i
/**
* 第四步: 处理父元素,因为图片都是绝对定位的,父元素必须是一个定位元素。
*/
function handleParent() {
var style = getComputedStyle(option.container); // 获取到父级的最终定位
if (style.position === "static") { // 如果父级没有定位 (为何要如此定位,因为万一父级有定位的情况下,我们要保证他不被影响)
option.container.style.position = "relative";// 设置父级为相对定位
}
}
那么,我们要知道一行内有多少张图?
还有他们之间的最小间隙
/**
* 第五步: 得到图片水平方向上的信息。
*/
function getHorizontalInfo() {
// 5.1 定义一个对象用来存储数据
var obj = {};
// 5.2 容器的宽度
obj.containerWidth = option.container.clientWidth;
// 5.3 计算一行有多少个图片
obj.number = (obj.containerWidth + option.minGap) / (option.imgWidth + option.minGap);
// 5.4 向下取整, 每行的图片只能少不能多。多了他会放不下
obj.number = Math.floor(obj.number);
// 5.5 重新计算每一个水平空隙
// 总宽度-图片的数量*图片的宽度=剩余空间
obj.gap = (obj.containerWidth - obj.number * option.imgWidth) / (obj.number - 1);
console.log(obj.gap);
return obj; // 返回这个对象
}
我们就来设置他们的top和left值
写一个setImgPosition函数
/**
* 第六步: 设置每一张图片的坐标
*/
function setImgPosition() {
// 6.1 获取水平方向信息保存到info变量中
var info = getHorizontalInfo();
// console.log(info);
// 第七步: 存放每一列下一张图片的top值
// 7.1 创建数组
var arr = new Array(info.number);
// 7.2 填充数组的每一项为0
arr.fill(0);
// 7.3 获取所有的图片
imgs.forEach(function (img) {
// 设置图片的坐标
// 7.4 找到数组里面的最小值
var minTop = Math.min.apply(null, arr);
// 7.5 图片的纵坐标
img.style.top = minTop + "px";
// 7.6 更新数组的top值(最小值拿的是数组的哪一项,找到对应的列编号。再更新)
var index = arr.indexOf(minTop);
// 设置数组当前这一项
// 图片当前的高度 + 垂直方向间隙
arr[index] += img.clientHeight + info.gap;
// 横坐标
img.style.left = index * (option.imgWidth + info.gap) + "px";
});
}
得到效果如下
所以应该是每一张图片加载完就给他重新设置高度
因此setImgPosition函数不能在外面调用,他应该在图片的事件中调用
img.onload = function () {
setImgPosition();
};
调用setImgPosition函数调用的就太频繁了
因此我们要使用函数防抖来限制他的频繁调用
在createImg函数中引用下面代码:
因此给container添加一个监听事件
// 窗口尺寸变化事件
var debounce = myPlugin.debounce(setImgPosition, 300, false);
window.onresize = function () {
debounce();
}
JS 行为
if (!window.myPlugin) {
window.myPlugin = {};
}
/**
* 第一步: 创建一个图片瀑布流
* @param {*} option 参数配置
*/
window.myPlugin.createWaterFall = function (option) {
// option默认值
var defaultOption = {
minGap: 10, // 图片最小间隙
imgSrcs: [], // 图片的路径数组
imgWidth: 220, // 单张图片的宽度
container: document.body // 需要渲染的容器
}
// 第二步: 对象混合
var option = Object.assign({}, defaultOption, option);
// console.log(option);
var imgs = []; // 存放所有的图片dom对象
// 处理父元素
handleParent();
// 3.1 创建图片
createImgs();
// 窗口尺寸变化事件
var debounce = myPlugin.debounce(setImgPosition, 300, false);
window.onresize = function () {
debounce();
}
/**
* 第五步: 设置每一张图片的坐标
*/
function setImgPosition() {
// 第七步: 获取水平方向信息
var info = getHorizontalInfo();
// console.log(info);
// 7.1 存放每一列下一张图片的top值
var arr = new Array(info.number);
// 7.2
arr.fill(0);
// console.log(arr);
// 7.3 获取所有的图片
imgs.forEach(function (img) {
// 设置图片的坐标
// 7.4 找到数组里面的最小值
var minTop = Math.min.apply(null, arr);
// 7.5 图片的坐标
img.style.top = minTop + "px";
// 7.6 更新数组的top值(最小值拿的是数组的哪一项,找到对应的列编号。再更新)
var index = arr.indexOf(minTop);
// 设置数组当前这一项
// 图片当前的高度 + 垂直方向间隙
arr[index] += img.clientHeight + info.gap;
// 横坐标
img.style.left = index * (option.imgWidth + info.gap) + "px";
});
// 设置容器的高度
var maxTop = Math.max.apply(null, arr);
option.container.style.height = maxTop - info.gap + "px";
}
/**
* 第六步: 得到图片水平方向上的信息。
*/
function getHorizontalInfo() {
// 6.1
var obj = {};
// 6.2 容器的宽度
obj.containerWidth = option.container.clientWidth;
// 6.3 计算一行有多少个图片
obj.number = (obj.containerWidth + option.minGap) / (option.imgWidth + option.minGap);
// 6.4 向下取整, 每行的图片只能少不能多。
obj.number = Math.floor(obj.number);
// 6.5 重新计算每一个水平空隙
// 总宽度-图片的数量*图片的宽度=剩余空间
obj.gap = (obj.containerWidth - obj.number * option.imgWidth) / (obj.number - 1);
console.log(obj.gap);
return obj;
}
/**
* 第三步: 创建图片
*/
function createImgs() {
// 函数节流
var debounce = myPlugin.debounce(setImgPosition, 50, false);
// 循环图片路径数组
for (var i = 0; i
结语
文章标题:原生JavaScript实现图片瀑布流效果,可更改配置参数 带完整版解析代码[waterFall.js]
文章链接:http://soscw.com/index.php/essay/48115.html