0

0

jQuery“加载更多”功能实现:动态更新隐藏元素集合的两种策略

DDD

DDD

发布时间:2025-11-04 10:31:11

|

363人浏览过

|

来源于php中文网

原创

jQuery“加载更多”功能实现:动态更新隐藏元素集合的两种策略

本文旨在解决使用jquery实现“加载更多”功能时,因未正确更新隐藏元素集合而导致后续内容无法加载的问题。我们将探讨两种核心策略:通过重新切片(re-slicing)动态更新已处理的隐藏元素列表,或在每次点击时重新查询dom以获取最新的隐藏元素。通过详细的代码示例和最佳实践,帮助开发者构建健壮且高效的无限滚动或分页加载功能。

在现代网页应用中,“加载更多”或无限滚动功能已成为提升用户体验的常见模式。它允许用户按需加载内容,而不是一次性加载所有数据,从而提高页面加载速度和响应性。然而,在实现这类功能时,尤其是使用jQuery操作DOM元素时,一个常见的逻辑陷阱是未能正确管理和更新当前可见及隐藏的元素集合。

问题描述

假设我们有一个包含多个卡片(insertCard)的列表,其中一部分卡片默认隐藏。我们希望通过点击一个“加载更多”按钮,每次显示固定数量(例如9个)的隐藏卡片。最初的代码逻辑可能如下:

$(function () {
  var loadmoreBtn = $('.resourceListing__loadmore');
  var hiddenCard = $('.insertCard:hidden'); // 初始获取所有隐藏卡片
  var x = 13; // 初始显示的卡片数量,这里可能与CSS规则相关

  loadmoreBtn.on('click', function (e) {
    e.preventDefault();
    x = x + 9; // 更新总数(虽然在这个逻辑中没有直接使用)
    console.log("click");
    hiddenCard.slice(0, 9).fadeIn().addClass("insertCard--flex"); // 显示前9个隐藏卡片
    if(hiddenCard.length == 0){
      loadmoreBtn.hide();
    }
  });
});

以及相应的CSS规则,用于初始隐藏部分卡片:

.resourceListing .insertCard:nth-child(n+16) {
  display: none; /* 默认隐藏第16个及之后的卡片 */
}

.insertCard {
  display: flex; /* 默认显示 */
}
.insertCard--flex {
  display: flex !important; /* 强制显示 */
}

这段代码的问题在于,var hiddenCard = $('.insertCard:hidden'); 这行代码只在页面加载时执行一次,获取了一个静态的隐藏卡片集合。当用户第一次点击“加载更多”按钮时,hiddenCard.slice(0, 9) 会正确地从这个初始集合中选择前9个卡片并显示。然而,在后续的点击中,hiddenCard 变量仍然引用的是最初的那个静态集合。因此,无论点击多少次,它总是尝试从这个未更新的集合中选择“前9个”卡片,导致后续的卡片无法被加载,或者重复加载相同的卡片(如果它们仍处于隐藏状态)。

解决方案一:动态更新隐藏元素集合(推荐)

解决这个问题的关键在于,每次显示一部分卡片后,我们需要更新 hiddenCard 变量,使其只包含那些尚未被显示的隐藏卡片。这可以通过对 hiddenCard 集合本身进行切片来实现。

核心思路: 在每次显示新的卡片后,将 hiddenCard 变量重新赋值为它自身的一个切片,该切片移除了刚刚被显示的那部分卡片。

修正后的JavaScript代码:

Adobe Image Background Remover
Adobe Image Background Remover

Adobe推出的图片背景移除工具

下载
$(function () {
  const loadmoreBtn = $('.resourceListing__loadmore');
  let hiddenCard = $('.insertCard:hidden'); // 使用let以便后续重新赋值
  const cardsToShowPerClick = 9; // 定义每次点击显示的卡片数量

  loadmoreBtn.on('click', function (e) {
    e.preventDefault();
    console.log("点击加载更多,当前隐藏卡片数量:", hiddenCard.length);

    // 1. 获取当前批次要显示的卡片
    const cardsToDisplay = hiddenCard.slice(0, cardsToShowPerClick);

    // 2. 显示这些卡片
    cardsToDisplay.fadeIn().addClass("insertCard--flex");

    // 3. 更新 hiddenCard 变量,移除已显示的卡片
    hiddenCard = hiddenCard.slice(cardsToShowPerClick);

    // 4. 检查是否还有更多隐藏卡片,如果没有则隐藏“加载更多”按钮
    if (hiddenCard.length === 0) {
      loadmoreBtn.hide();
    }
  });
});

代码解释:

  1. let hiddenCard = $('.insertCard:hidden');:我们使用 let 而不是 var,因为 hiddenCard 变量在后续会被重新赋值。
  2. const cardsToDisplay = hiddenCard.slice(0, cardsToShowPerClick);:在每次点击时,我们从当前的 hiddenCard 集合中取出前 cardsToShowPerClick 个元素。
  3. cardsToDisplay.fadeIn().addClass("insertCard--flex");:将这些选中的卡片设置为可见。
  4. hiddenCard = hiddenCard.slice(cardsToShowPerClick);:这是最关键的一步。它将 hiddenCard 变量重新赋值为原 hiddenCard 集合从索引 cardsToShowPerClick 开始的剩余部分。这样,下一次点击时,hiddenCard 就会引用一个只包含未显示卡片的集合。
  5. if (hiddenCard.length === 0):当所有隐藏卡片都被显示后,hiddenCard 的长度将变为0,此时隐藏“加载更多”按钮,防止用户继续点击。

解决方案二:每次点击时重新查询DOM

另一种更直接但可能效率稍低的方法是,在每次点击“加载更多”按钮时,重新查询DOM以获取当前所有隐藏的卡片。

核心思路: 将 $('.insertCard:hidden') 的查询操作移动到点击事件处理函数内部。

修正后的JavaScript代码:

$(function () {
  const loadmoreBtn = $('.resourceListing__loadmore');
  const cardsToShowPerClick = 9;

  loadmoreBtn.on('click', function (e) {
    e.preventDefault();
    // 每次点击时重新查询所有隐藏卡片
    const hiddenCard = $('.insertCard:hidden'); 
    console.log("点击加载更多,当前隐藏卡片数量:", hiddenCard.length);

    // 获取当前批次要显示的卡片
    const cardsToDisplay = hiddenCard.slice(0, cardsToShowPerClick);

    // 显示这些卡片
    cardsToDisplay.fadeIn().addClass("insertCard--flex");

    // 检查是否还有更多隐藏卡片,如果没有则隐藏“加载更多”按钮
    // 注意:这里需要再次查询,或者判断 cardsToDisplay.length 是否小于 cardsToShowPerClick
    // 更准确的判断是,如果显示完当前批次后,剩余的隐藏卡片数量为0
    if (hiddenCard.length <= cardsToShowPerClick) { // 如果当前隐藏卡片数量小于或等于要显示的数量,则下一批次就没有了
      loadmoreBtn.hide();
    }
  });
});

代码解释:

  1. const hiddenCard = $('.insertCard:hidden');:这行代码现在位于 click 事件处理函数内部。这意味着每次点击按钮时,jQuery都会重新扫描DOM,找到所有当前 display: none 的 .insertCard 元素,并创建一个新的集合。
  2. 这种方法确保了 hiddenCard 总是最新的,因为它反映了DOM的当前状态。

两种解决方案的比较:

  • 解决方案一(动态更新集合):
    • 优点: 性能通常更好,因为它避免了每次点击时都进行完整的DOM查询。对于有大量元素的页面,DOM查询可能比较耗时。
    • 缺点: 需要更细致的状态管理,确保 hiddenCard 变量始终是正确的。
  • 解决方案二(重新查询DOM):
    • 优点: 逻辑更简单,更直观,不易出错,因为每次都获取最新的DOM状态。
    • 缺点: 可能会有性能开销,尤其是在页面元素非常多,或者点击频率很高的情况下。

通常,对于中小型列表,两种方法都能很好地工作。但如果列表非常庞大,或者对性能有严格要求,解决方案一会是更好的选择。

完整的HTML结构和CSS样式

为了使上述JavaScript代码正常工作,我们需要一个相应的HTML结构和CSS样式来定义卡片的初始状态和“加载更多”按钮。

HTML结构示例:




Card 1
Card 2
Placeholder 1
Card 3
Card 4
Placeholder 2
Card 5
Card 6
Card 7
Card 8
Card 9
Card 10
Card 11
Card 12
Card 13
Card 14
Card 15
Card 16
Card 17
Card 18
Card 19
Card 20
Card 21
Card 22
Card 23
Card 24
Card 25

CSS样式示例:

:root {
  --black: #000000;
  --white: #FFFFFF;
  --navy: #0E185F;
}

.placeholderCard,
.resourceCard {
  padding: 60px;
  border: 1px solid var(--black);
  margin-bottom: 30px;
  width: 100%;
}

.placeholderCard {
  background: var(--navy);
  color: var(--white);
  padding: 20px;
}

.resourceListing {
  padding: 80px 0;
}
.resourceListing__loadmore {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 60px 0;
  cursor: pointer;
  /* 基础按钮样式 */
  padding: 10px 20px;
  background-color: var(--navy);
  color: var(--white);
  border-radius: 5px;
  text-decoration: none;
}
/* 初始隐藏规则:从第16个卡片开始隐藏 */
.resourceListing .insertCard:nth-child(n+16) { 
  display: none;
}

.insertCard {
  display: flex; /* 默认显示,但会被nth-child规则覆盖 */
}
.insertCard--flex {
  display: flex !important; /* 用于强制显示被JavaScript激活的卡片 */
}

注意事项与最佳实践

  1. 使用 const 和 let: 在现代JavaScript中,推荐使用 const 定义常量(值不会改变的变量),使用 let 定义变量(值可能会改变的变量),而不是 var。这有助于避免作用域问题和提高代码可读性。
  2. 错误处理/边界情况: 在实际应用中,应考虑当没有更多卡片可加载时,“加载更多”按钮的状态管理。例如,当 hiddenCard.length 为0时,隐藏按钮以防止用户不必要的点击。
  3. 用户体验: 考虑在加载过程中显示一个加载指示器(例如旋转图标),以告知用户内容正在加载,提高用户体验。
  4. 性能优化: 如果卡片数量非常巨大,可以考虑使用虚拟滚动或更高级的懒加载技术,而不是一次性渲染所有DOM元素。
  5. 语义化HTML: 确保你的HTML结构是语义化的,例如使用
    • 来表示列表项,而不是通用的
      ,这有助于可访问性和SEO。

      总结

      实现“加载更多”功能时,关键在于正确管理和更新隐藏元素的集合。通过动态更新JavaScript变量中的元素引用(解决方案一)或在每次交互时重新查询DOM(解决方案二),我们可以确保每次点击都能加载到新的、未显示的内容。在选择具体实现方式时,应权衡性能需求和代码的简洁性。遵循现代JavaScript的最佳实践,并结合良好的用户体验设计,将能构建出高效且用户友好的内容加载体验。

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

557

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

374

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

754

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

478

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

434

2023.09.04

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

1031

2023.09.04

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

658

2023.09.12

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

553

2023.09.20

Java编译相关教程合集
Java编译相关教程合集

本专题整合了Java编译相关教程,阅读专题下面的文章了解更多详细内容。

0

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.8万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

CSS教程
CSS教程

共754课时 | 21.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号