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

JavaScript过滤/映射后页面刷新:联系人列表重复添加问题求解

解决联系人列表点击按钮重复追加的问题

我基于随机用户API开发了联系人列表功能,页面包含输入框与按钮,点击按钮后要么加载新的10条用户数据并存入localStorage,要么根据输入框内容过滤已有数据。但当前遇到的问题是:每次点击按钮后,新数据都会追加到原有列表的后面,无法实现点击后刷新显示对应结果的效果。


问题原因

问题出在printData函数中:每次渲染数据时,都直接通过ul.appendChild(li)向列表容器添加新元素,但没有先清空容器内已有的内容,导致旧数据保留,新数据不断叠加。

解决方案

在渲染新数据之前,先清空列表容器的内容,推荐两种简洁高效的方式:

  • 直接设置容器的innerHTML为空字符串:ul.innerHTML = ''
  • 循环移除所有子元素:while (ul.firstChild) ul.removeChild(ul.firstChild)

优先选择第一种方式,代码更简洁直观。


修改后的完整代码

JavaScript代码

async function fetchPeople() {
  const URL = 'https://randomuser.me/api/?results=10';
  const res = await fetch(URL);
  let data = await res.json();
  return data;
}

async function data(name) {
  let filteredData = [];

  if (name.length > 0) {
    let newdata = JSON.parse(localStorage.getItem('contacts'));
    filteredData = newdata.filter((contact) => {
      return contact.name.first.toLowerCase().includes(name);
    });
  } else {
    let data = await fetchPeople();
    localStorage.setItem('contacts', JSON.stringify(data.results));
    filteredData = data.results;
  }
  return filteredData;
}

async function printData() {
  let ul = document.querySelector('#cards');
  let name = document.querySelector('#contact').value.toLowerCase();
  let filteredData = await data(name);

  // 关键:先清空容器内旧内容
  ul.innerHTML = '';

  filteredData.forEach((contact) => {
    let li = document.createElement('li');
    li.innerHTML = `
      <div class="card">
        <img src="${contact.picture.large}"
          alt="${contact.name.first} ${contact.name.last}"
          class="card__image">
        <h2 class="card__name">${contact.name.first}  ${contact.name.last}</h2>
        <p class="card__email">${contact.email}</p>
        <p class="card__location">${contact.location.city}-${contact.location.state}</p>
        <button class="card__btn">${contact.location.country}</button>
      </div>`;
    ul.appendChild(li);
  });
}

HTML代码

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<section class="form">
  <div class="search">
    <h1>Contact List</h1>
    <div class='search__field'>
      <input type="text" name="contact" id="contact" placeholder="Nome do contato" class="search__name form-control">
      <button type="button" onclick='printData()' class='btn btn-primary search__btn'>Search</button>
    </div>
  </div>
</section>
<section class="results">
  <ul class="cards" id="cards"></ul>
</section>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>

额外优化说明

同时简化了data函数中多余的return语句:原else分支里的return filteredData被移除,因为函数末尾已经统一返回该变量,逻辑更简洁统一。

内容的提问来源于stack exchange,提问作者Kelson Batista

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 08:25:14