You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 10:42:22