如何用Vanilla JS确保API返回数据的页面展示顺序与响应一致?
排序参数生效但页面展示顺序错误问题
我尝试通过传递asc和desc排序参数从API获取产品列表,点击下拉框的desc选项后,API返回的数据是正确的,但页面上的元素展示顺序却出错了。
问题展示:
相关代码
const app = document.getElementById("app"); const table = document.createElement("table"); const loader = document.createElement("div"); const API_URL = `https://fakestoreapi.com`; let ORDER = `asc`; loader.innerHTML = `Loader..`; function hideLoader() { app.removeChild(loader); } function showLoader() { app.appendChild(loader); } app.innerHTML = ` <h1>List</h1> `; const select = document.createElement("select"); const option1 = document.createElement("option"); const option2 = document.createElement("option"); option1.value = "aesc"; option1.innerHTML = "aesc"; option2.value = "desc"; option2.innerHTML = "desc"; select.appendChild(option1); select.appendChild(option2); app.appendChild(select); select.addEventListener("change", (e) => handleChange(e)); function handleChange(e) { fetchData(e.target.value); } async function fetchData(order) { showLoader(); const response = await fetch(`${API_URL}/products?sort=${order}`); const data = await response.json(); displayData(data); } function displayData(data) { const tbody = document.createElement("tbody"); console.log("data", data); data.forEach((item) => { const tr = document.createElement("tr"); tr.key = item.id; tr.innerHTML = ` <td>${item.id}</td> <td>${item.title}</td> <td>${item.price}</td> `; tbody.appendChild(tr); }); table.appendChild(tbody); app.appendChild(table); hideLoader(); } fetchData(ORDER);
问题原因及修复方法
问题根源
- 表格数据未清空:每次调用
displayData时,都会新建一个<tbody>并追加到已有<table>中,旧数据没有被清除,新数据只是叠加在后面,导致视觉上排序无效。 - 参数拼写错误:下拉框中"asc"被写成了"aesc",虽然API可能兼容错误参数,但这是不规范的写法。
修复步骤
- 修正参数拼写:将下拉框第一个选项的
value和文本内容从aesc改为asc:
option1.value = "asc"; option1.innerHTML = "asc";
- 清空旧表格数据:在
displayData函数开头,先清空表格内的所有内容,再添加新的<tbody>:
function displayData(data) { // 清空表格现有内容 table.innerHTML = ""; const tbody = document.createElement("tbody"); console.log("data", data); data.forEach((item) => { const tr = document.createElement("tr"); tr.key = item.id; tr.innerHTML = ` <td>${item.id}</td> <td>${item.title}</td> <td>${item.price}</td> `; tbody.appendChild(tr); }); table.appendChild(tbody); hideLoader(); }
- 优化DOM操作:初始化时就将
table添加到app中,避免每次渲染重复执行app.appendChild(table):
// 初始化阶段添加table到app app.appendChild(table);
内容的提问来源于stack exchange,提问作者Subhojit
相关产品推荐
相关产品推荐

