jQuery实现作品集卡片分类筛选时append仅追加1个卡片的问题
问题根源
- 事件绑定位置错误:你把分类按钮的
click事件绑定写在了遍历卡片的for循环内部,每遍历1张卡片就会给按钮重复绑定1次回调,最终每个分类按钮绑定的回调数量和卡片总数相等。点击按钮时所有回调会依次触发:每触发一个匹配标签的回调,就先执行empty()清空容器,再追加当前遍历到的单张卡片,之前追加的卡片会被直接删掉,最终只会留下最后一个匹配到的卡片,这就是同分类下仅1张卡片能渲染的核心原因。 - DOM操作过于频繁:循环内反复执行清空、追加DOM的操作,会触发浏览器多次重排重绘,这也是你加
setTimeout延迟处理时出现元素位移、页面闪烁卡顿的根本原因。 - 模板语法错误:卡片模板中Live预览图的
alt属性缺失等号,写成了alt"Live",会导致浏览器解析属性异常。
修复方案
核心调整思路:把事件绑定移出循环,仅在页面初始化时绑定1次;点击分类后先统一清空容器,将所有匹配分类的卡片拼接成完整HTML字符串后一次性追加,把DOM操作次数降到最低,从根源解决卡顿闪烁问题。
修复后的完整实现代码如下:
const projects = { cards: { card1: { name: "", skills: "", thumbnail: "", github: "", live: "", tag: "webdevelopment", underConstruction: "no" }, card2: { name: "", skills: "", thumbnail: "", github: "", live: "", tag: "webdevelopment", underConstruction: "no" }, card3: { name: "", skills: "", thumbnail: "", github: "", live: "", tag: "devOps", underConstruction: "no" }, }, // 抽离公共卡片渲染方法,避免重复编写模板 renderCards: (filterTag = null) => { const cardList = Object.values(projects.cards); const container = $('.project-container'); container.empty(); let cardHtml = ''; cardList.forEach(card => { const currentTag = card.tag.toLowerCase(); // 未传筛选标签时渲染全量卡片,传值时仅渲染匹配分类的卡片 if (!filterTag || currentTag === filterTag) { // 同步修复原模板alt属性缺等号的语法错误 cardHtml += ` <div class="card" data-skills="${card.skills}"> <div class="card-thumbnail"> <img src="${card.thumbnail}" alt="${card.name}"> </div> <div class="card-link"> <a href="${card.live}" target="_rel"><img src="iamtt/../assets/images/live.png" alt="Live"></a> <a href="${card.github}" target="_rel"><img src="iamtt/../assets/images/github-live.png" alt="github"></a> </div> </div> ` } }) // 一次性追加所有卡片,仅触发1次浏览器重绘,完全无闪烁卡顿 container.append(cardHtml); }, initSort: () => { // 页面初始化默认渲染全量项目 projects.renderCards(); // 分类点击事件仅绑定1次 $('.webdevelopment').click(() => { projects.renderCards('webdevelopment'); }) $('.devops').click(() => { projects.renderCards('devops'); }) // 后续如果要加「全部项目」按钮,直接调用projects.renderCards()即可,无需修改渲染逻辑 } } // 页面DOM加载完成后初始化筛选功能 $(function(){ projects.initSort(); })
优化说明
- 逻辑解耦:将卡片渲染、事件初始化逻辑拆分,后续新增项目分类只需要加1行点击绑定代码,不需要重复写卡片模板
- 性能提升:将原来循环内N次DOM清空、追加操作合并为1次,彻底解决页面位移、闪烁卡顿问题
- 兼容性更好:统一做标签小写转换比对,避免因为大小写不一致导致的匹配失效问题
- 扩展性更强:预留全量渲染入口,后续加全部分类、多标签筛选等功能不需要重构核心逻辑
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

