当前位置:首页 > JavaScript

js实现瀑布流

2026-02-28 18:50:32JavaScript

实现瀑布流布局

瀑布流布局是一种常见的网页布局方式,适用于图片、卡片等内容的展示。通过 JavaScript 实现瀑布流布局,可以动态计算元素的位置,确保每一列的高度均衡。

基础实现步骤

HTML 结构

<div class="waterfall-container">
  <div class="waterfall-item">Item 1</div>
  <div class="waterfall-item">Item 2</div>
  <div class="waterfall-item">Item 3</div>
  <!-- 更多 item -->
</div>

CSS 样式

js实现瀑布流

.waterfall-container {
  position: relative;
  width: 100%;
}

.waterfall-item {
  position: absolute;
  width: 200px; /* 固定宽度 */
  margin-bottom: 20px; /* 间距 */
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
}

JavaScript 逻辑

function initWaterfall() {
  const container = document.querySelector('.waterfall-container');
  const items = document.querySelectorAll('.waterfall-item');
  const columnCount = 3; // 列数
  const gap = 20; // 间距
  const itemWidth = 200; // 与 CSS 中的宽度一致
  const containerWidth = container.offsetWidth;

  // 计算列宽(考虑间距)
  const columnWidth = (containerWidth - (gap * (columnCount - 1))) / columnCount;

  // 初始化列高数组
  const columnHeights = new Array(columnCount).fill(0);

  // 遍历每个 item,计算位置
  items.forEach(item => {
    // 找到当前高度最小的列
    const minHeight = Math.min(...columnHeights);
    const columnIndex = columnHeights.indexOf(minHeight);

    // 设置 item 的位置
    const left = columnIndex * (columnWidth + gap);
    const top = minHeight;

    item.style.width = `${columnWidth}px`;
    item.style.left = `${left}px`;
    item.style.top = `${top}px`;

    // 更新列高
    columnHeights[columnIndex] += item.offsetHeight + gap;
  });

  // 设置容器高度
  container.style.height = `${Math.max(...columnHeights)}px`;
}

// 初始化瀑布流
window.addEventListener('load', initWaterfall);
window.addEventListener('resize', initWaterfall);

动态加载更多内容

如果需要滚动加载更多内容,可以通过监听滚动事件动态添加新元素并重新计算布局。

js实现瀑布流

let isLoading = false;

function loadMoreItems() {
  if (isLoading) return;
  isLoading = true;

  // 模拟异步加载数据
  setTimeout(() => {
    const container = document.querySelector('.waterfall-container');
    const fragment = document.createDocumentFragment();

    // 添加新元素(示例)
    for (let i = 0; i < 10; i++) {
      const item = document.createElement('div');
      item.className = 'waterfall-item';
      item.textContent = `New Item ${i + 1}`;
      fragment.appendChild(item);
    }

    container.appendChild(fragment);
    initWaterfall(); // 重新计算布局
    isLoading = false;
  }, 1000);
}

// 监听滚动事件
window.addEventListener('scroll', () => {
  const scrollTop = document.documentElement.scrollTop;
  const windowHeight = window.innerHeight;
  const documentHeight = document.documentElement.scrollHeight;

  // 滚动到底部时加载更多
  if (scrollTop + windowHeight >= documentHeight - 100) {
    loadMoreItems();
  }
});

使用 CSS Grid 简化实现

如果不需要支持过旧的浏览器,可以使用 CSS Grid 简化瀑布流布局的实现。

CSS 样式

.waterfall-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-gap: 20px;
  grid-auto-flow: dense;
}

.waterfall-item {
  break-inside: avoid; /* 避免内容断裂 */
}

JavaScript 调整

function adjustGridLayout() {
  const container = document.querySelector('.waterfall-container');
  const items = document.querySelectorAll('.waterfall-item');

  items.forEach(item => {
    const rowHeight = Math.ceil(item.offsetHeight / 20) * 20;
    item.style.gridRowEnd = `span ${rowHeight}`;
  });
}

window.addEventListener('load', adjustGridLayout);
window.addEventListener('resize', adjustGridLayout);

注意事项

  • 性能优化:对于大量元素,使用 DocumentFragment 减少 DOM 操作次数。
  • 图片加载:如果内容包含图片,需监听图片加载完成后再计算布局,避免高度计算错误。
  • 响应式设计:动态调整列数以适配不同屏幕尺寸。

以上方法提供了基础的瀑布流实现,可根据实际需求进一步扩展功能。

标签: 瀑布js
分享给朋友:

相关文章

js实现拖拽

js实现拖拽

实现拖拽的基本步骤 通过监听鼠标事件(mousedown、mousemove、mouseup)实现拖拽功能。以下是核心代码逻辑: const draggableElement = document.…

js防抖和节流实现

js防抖和节流实现

防抖(Debounce)的实现 防抖的核心思想是在事件被触发后,延迟执行回调函数。如果在延迟时间内再次触发事件,则重新计时。适用于输入框搜索、窗口大小调整等场景。 function debounce…

js实现pdf在线预览

js实现pdf在线预览

使用PDF.js实现PDF在线预览 PDF.js是由Mozilla开发的一个开源JavaScript库,可以在网页中直接渲染PDF文件。以下是实现PDF在线预览的步骤: 引入PDF.js库 在HT…

js实现点击显示和隐藏

js实现点击显示和隐藏

实现点击显示和隐藏的JavaScript方法 使用classList.toggle切换类名 通过添加/移除CSS类控制元素的显示与隐藏,需提前在CSS中定义隐藏样式(如display: none)。…

js实现防洪

js实现防洪

防抖(Debounce)实现 防抖的核心思想是在事件触发后延迟执行回调函数,若在延迟时间内再次触发事件,则重新计时。适用于输入框搜索、窗口调整等场景。 function debounce(f…

链表实现js

链表实现js

链表的基本概念 链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和一个指向下一个节点的指针(单向链表)或两个指针(双向链表)。与数组不同,链表在内存中非连续存储,插入和删除操作更高效,但随机…