这是一篇给大学生正在学js看的,工作了的不用看了,为什么不用看呢,因为我怕被你们笑,而我这篇文章只能给清澈而又清澈的大学生,莫笑莫笑。 在很多特效中,我们会看到轮播图,计时器这类的特效,然而深究他的原理都会发现是在操作dom之类的,然后用算法的思维去计算,当然这篇文章的也是。 这篇文章的核心算法是主要获取每列的最小高度,然后将图片放在最小的高度中,其他的就没有了。 代码都已经贴,图片的话,大家自己网上找就好,然后不懂的再评论区讨论
// 先贴一下用算法计算他的最小高度
const getMinHeight = (arr) => {
// 第一种算法
const minHeight = arr[0];
for(let i = 0, length = arr.length; i < length; i++) {
if(arr[i] < minHeight) {
minHeight = arr[i];
}
}
return minHeight;
// 第二种 算法
// return Math.min(...arr)
// 第三种算法
// return Math.min.call(null, arr)
}
// 然后设置图片的位置
const setPositions () => {
const {
columns,
space
} = getColumns();
const arr = new Array(columns).fill(0); // 定义列高数组并初始化为0
const imgs = container.querySelectorAll("#container img"); // 获取所有图片元素
for (let i = 0; i < imgs.length; i++) {
const img = imgs[i]; // 获取当前的图片
const minTop = getMinHeight(arr); // 获取当前图片的最小高度
const index = arr.indexOf(minTop); // 获取最小高度的索引
arr[index] += img.height + space; // 更新对应列的高度
const left = (index + 1) * space + index * imgWidth; // 设置图片的left值
img.style.transform = `translate(${left}px, ${minTop}px)`; // 使用transform设置位置
}
maxHeight = getMaxHeight(arr); // 获取最大高度
}
废话不多说,我直接贴源码吧,不懂的,评论上讨论哈哈哈哈
css 代码
* {
padding: 0px;
margin: 0px;
}
.container {
margin: 20px auto;
width: 90%;
height: 100%;
position: relative;
border: 1px solid #ccc;
}
.container img {
position: absolute;
transition: all 0.3s ease;
}
js 代码
// 获取最小值
const getMinHeight = arr => {
return Math.min.call(null, ...arr)
}
// 获取最大值
const getMaxHeight = arr => {
return Math.max.call(null, ...arr)
}
// 定义一个防抖函数
const debounce = (func, dealy) => {
let timer = null;
return function (...args) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args)
}, dealy);
}
}
const container = document.querySelector("#container")
// 定义常量值
const imgWidth = 220
let maxHeight = 0
// 获取返回列数
const getColumns = arr => {
const containerWidth = container.clientWidth; // 获取容器宽度
const columns = Math.floor(containerWidth / imgWidth); // 计算列数
const extraSpace = containerWidth - columns * imgWidth; // 计算剩余宽度
const spaceNum = columns + 1; // 间距数量
const space = Math.floor(extraSpace / spaceNum); // 计算间距
return {
columns,
space
}
}
// 设置图片位置
const setPositions = () => {
const {
columns,
space
} = getColumns();
const arr = new Array(columns).fill(0); // 定义列高数组并初始化为0
const imgs = container.querySelectorAll("#container img"); // 获取所有图片元素
for (let i = 0; i < imgs.length; i++) {
const img = imgs[i]; // 获取当前的图片
const minTop = getMinHeight(arr); // 获取当前图片的最小高度
const index = arr.indexOf(minTop); // 获取最小高度的索引
arr[index] += img.height + space; // 更新对应列的高度
const left = (index + 1) * space + index * imgWidth; // 设置图片的left值
img.style.transform = `translate(${left}px, ${minTop}px)`; // 使用transform设置位置
}
maxHeight = getMaxHeight(arr); // 获取最大高度
}
const createImage = () => {
const fragment = document.createDocumentFragment() // 添加文档碎片留
for (let i = 1; i <= 17; i++) {
const img = document.createElement("img")
if (i < 10) {
img.src = `./images/0${i}.jpg`
} else {
img.src = `./images/${i}.jpg`
}
img.style.width = `${imgWidth}px`
img.onload = setPositions
fragment.appendChild(img)
}
container.appendChild(fragment);
container.style.height = `${maxHeight}px`;
}
// 监听窗口变化
const bindEvent = () => {
const handleResize = () => {
setPositions();
container.style.height = `${maxHeight}px`;
};
const debouncedHandleResize = debounce(handleResize, 500);
window.addEventListener("resize", debouncedHandleResize);
}
// 主函数入口
const main = () => {
createImage();
bindEvent();
}
main()
html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图片瀑布流</title>
<style></style>
<link rel="stylesheet" href="./css/index.css" preload />
<script src="./js/index.js" defer></script>
</head>
<body>
<div class="container" id="container"></div>
</body>
</html>