本文教你用纯 javascript 实现一个可复用的“切换按钮”,点击时动态加载后端数据并展示列表,再次点击则隐藏列表——避免重复追加、确保界面干净可控。
本文教你用纯 javascript 实现一个可复用的“切换按钮”,点击时动态加载后端数据并展示列表,再次点击则隐藏列表——避免重复追加、确保界面干净可控。
要实现「点击显示数据,再点击隐藏」的交互效果,核心在于状态管理与DOM 控制:不能每次点击都无条件追加元素(否则列表会不断堆积),而应统一维护一个容器(如 <ul id="result">),通过控制其可见性 + 按需清空/重绘来实现真正的“切换”。
以下是优化后的完整实现方案:
✅ 正确做法:状态感知 + 容器复用
<button id="show_countries">切换国家列表</button> <ul id="result" style="display: none;"></ul>
const button = document.getElementById('show_countries');
const result = document.getElementById('result');
// 清空列表的辅助函数(推荐封装,提升可维护性)
const clearResult = () => {
result.innerHTML = '';
};
// 加载并渲染数据
const fetchData = async () => {
try {
const response = await fetch('http://localhost:3003/countries');
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
console.log('获取到国家数据:', data);
// ✅ 关键:先清空,再渲染,杜绝重复叠加
clearResult();
data.forEach(country => {
const li = document.createElement('li');
li.textContent = country.name || '未知国家';
result.appendChild(li);
});
} catch (err) {
console.error('获取数据失败:', err);
clearResult(); // 出错时也确保容器干净
result.insertAdjacentHTML('beforeend', '<li style="color:red;">加载失败,请重试</li>');
}
};
// 切换逻辑:显示/隐藏 + 按需加载
const toggleResult = () => {
if (result.style.display === 'none') {
result.style.display = 'block';
fetchData(); // 首次显示时加载数据
} else {
result.style.display = 'none';
}
};
button.addEventListener('click', toggleResult);⚠️ 注意事项
- 不要依赖 innerHTML = '' 以外的方式清空:removeChild() 或循环 lastElementChild 虽可行,但 innerHTML = '' 更简洁高效(现代浏览器已优化)。
- 避免多次绑定事件:原代码中 addEventListener 写在函数外且只执行一次,是正确写法;切勿在 fetchData 内重复绑定。
- 增强健壮性:添加 HTTP 状态检查(如 response.ok)和错误 UI 反馈,提升用户体验。
- 进阶建议:如需支持“加载中”状态,可在 fetchData 开始前设置 result.innerHTML = '<li>加载中...</li>',并在成功/失败后覆盖。
通过该方案,你获得的是一个真正意义上的切换(toggle)行为——语义清晰、逻辑可控、无内存泄漏风险,也为你后续扩展(如缓存数据、添加动画、支持多数据源)打下坚实基础。

















