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

点击加载更多按钮后帖子索引偏移+3模态框数据不匹配问题

帖子加载后模态框数据错位问题修复

问题核心原因

  • 事件绑定的元素选择范围错误:你用document.querySelectorAll("ul")选择元素绑定点击事件时,会把页面内所有<ul>标签都纳入匹配范围,包括模态框里的内容列表、评论列表,根本不是只匹配帖子列表项。加载次数越多,页面里累积的非帖子ul越多,forEach遍历得到的索引偏移量就越大,第三次加载后偏移+3就是页面里多了非帖子类ul标签导致的。
  • 重复绑定事件:每次执行contentLoad()都会给已经渲染过的旧帖子、模态框关闭按钮重复绑定事件,既浪费性能,也会导致事件触发时取值混乱。
  • DOM操作位置错误:你把更新帖子容器内容、隐藏加载提示的逻辑写在了for循环内部,每遍历一条帖子就重写一次整个容器的DOM,会造成不必要的性能损耗,也容易触发渲染异常。

修复思路

  • 给每个帖子项加专属类名post-item,渲染时直接把帖子的真实ID、用户ID存在DOM的data-*自定义属性上,点击时直接读取属性取值,完全不依赖元素在页面里的位置索引,从根源避免错位。
  • 把HTML拼接和DOM操作拆开:for循环只负责拼接帖子的HTML字符串,全部拼接完成后再一次性插入到帖子容器里,减少DOM重排次数。
  • 用事件委托代替逐元素绑定事件:只需要在帖子父容器.post-content上绑定一次点击监听,动态加载的新帖子会自动响应点击,不需要每次加载都重新绑定,也不会出现重复绑定的问题。
  • 模态框关闭按钮的监听单独绑定一次,不要嵌套在帖子点击事件里。

修复后核心代码

fetch(`https://jsonplaceholder.typicode.com/posts`)
  .then((response) => response.json())
  .then((data) => {
    let count = 12;
    const postContent = document.querySelector(".post-content");
    const myModal = document.getElementById("myModal");
    const modalData = document.querySelector(".modal-data");
    const modalComments = document.querySelector(".modal-comments");
    const loading = document.getElementById("loading");
    const loadBtn = document.querySelector(".btn");
    const alertTip = document.querySelector(".alert");

    // 单独绑定一次模态框关闭事件
    document.getElementById("close").addEventListener("click", () => {
      myModal.style.display = "none";
    });

    // 事件委托绑定帖子点击事件,仅绑定一次,后续新加载的帖子自动生效
    postContent.addEventListener("click", (e) => {
      // 精准定位点击的帖子项
      const postItem = e.target.closest(".post-item");
      if (!postItem) return;
      // 直接从自定义属性读取真实帖子ID,不存在索引错位问题
      const postId = Number(postItem.dataset.postId);
      const post = data.find(item => item.id === postId);

      // 拉取作者信息
      fetch(`https://jsonplaceholder.typicode.com/users/${post.userId}`)
        .then((response) => response.json())
        .then((dataUser) => {
          // 渲染模态框基础内容
          modalData.innerHTML = ` 
            <ul class='list-group my-4'>
              <li class='list-group-item'><span class='fw-bold'>ID:</span>  ${post.id}</li>
              <li class='list-group-item'><span class='fw-bold'>User Name:</span> ${dataUser.name}</li>
              <li class='list-group-item'><span class='fw-bold'>Title:</span>  ${post.title}</li>
              <li class='list-group-item'><span class='fw-bold'>Post:</span>  ${post.body}</li>
              <li class='list-group-item'><span class='fw-bold'>Location:</span>  ${dataUser.address.city}</li>
              <li class='list-group-item'><span class='fw-bold'>Company:</span>  ${dataUser.company.name}</li>
            </ul>`;
          myModal.style.display = "block";

          // 拉取对应评论
          fetch(`https://jsonplaceholder.typicode.com/comments?postId=${post.id}`)
            .then((response) => response.json())
            .then((dataComment) => {
              let comments = "";
              // 筛选id模3等于0的评论
              for (let c = 0; c < dataComment.length; c++) {
                if (dataComment[c].id % 3 == 0) {
                  comments += `
                    <ul class='item-group'>
                      <li class='list-group-items'> <span class='fw-bold'>Id:</span> ${dataComment[c].id}</li>
                      <li class='list-group-items'> <span class='fw-bold'>Email:</span> ${dataComment[c].email}</li>
                      <li class='list-group-items'> <span class='fw-bold'>Comment:</span> ${dataComment[c].body}</li>
                    </ul>`;
                }
              }
              modalComments.innerHTML = comments;
            })
            .catch((error) => console.log(error));
        })
        .catch((error) => console.log(error));
    })

    function contentLoad() {
      let showPosts = "";
      for (let i = 0; i < count; i++) {
        // 给帖子项加专属类名,挂载自定义帖子ID属性
        showPosts += `
          <ul class='list-group my-4 post-item' data-post-id="${data[i].id}">
            <li class='list-group-item'><span class='fw-bold'>ID: </span>  ${data[i].id}</li>
            <li class='list-group-item'><span class='fw-bold'>Title: </span>  ${data[i].title}</li>
            <li class='list-group-item'><span class='fw-bold'>Post: </span>  ${data[i].body.split(" ").splice(0, 3).join(" ")}</li>
          </ul>`;
      }
      // 循环结束后一次性更新DOM,减少不必要的重绘
      postContent.innerHTML = showPosts;
      loading.style.display = "none";
    }

    // 首次加载帖子
    contentLoad();

    // 加载更多按钮逻辑
    loadBtn.addEventListener("click", function () {
      count = count + 12;
      if (count > 96) {
        loadBtn.style.display = "none";
        alertTip.style.display = "block";
      }
      contentLoad();
    });
  })
  .catch((error) => {
    console.log(error);
  });

内容的提问来源于stack exchange,提问作者Лука Траиловић

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:30:43