如何每隔几秒用更新数据刷新EJS局部视图?
解决方案:定时更新EJS局部视图内容
问题背景
需要每5秒通过fetch获取新数据,更新页面表格内容,希望直接复用已有EJS局部视图,避免手动拼接DOM元素,但尝试的方法均存在问题:
- 直接在EJS模板中使用
setInterval无效,因为EJS是服务器端渲染,运行时无法触发客户端定时逻辑 - 手动清除并重建DOM元素,运行几次后仅显示奇数项,逻辑复杂且易出bug
- 使用
<meta>标签会刷新整个页面,不符合局部更新需求
解决步骤
1. 新增返回局部视图的API路由
在现有Express路由中添加一个专门返回列表局部视图的接口,让前端可以直接请求渲染好的HTML片段:
app.get("/tracker/listings", async (req, res) => { const response = await fetch("https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=100&page=1&sparkline=false&price_change_percentage=1h%2C24h%2C7d"); const listings = await response.json(); // 直接渲染局部视图并返回HTML res.render("./partials/list", { listings }); });
2. 前端实现定时更新逻辑
在页面的客户端JS中(可放在index.ejs的<script>标签或单独JS文件),用setInterval定时请求上述API,拿到新HTML后直接替换tbody内容:
document.addEventListener("DOMContentLoaded", () => { // 定义更新函数 async function updateListings() { try { const response = await fetch("/tracker/listings"); const newHtml = await response.text(); // 替换目标tbody的内容 document.getElementById("listings").innerHTML = newHtml; } catch (error) { console.error("更新列表失败:", error); } } // 页面加载后立即执行一次,避免等待5秒才显示内容 updateListings(); // 每5秒触发一次更新 setInterval(updateListings, 5000); });
3. 原手动DOM操作的问题说明
之前的手动更新逻辑存在多处错误:
forEach是同步方法,无需添加await,多余的await会导致逻辑混乱- 错误地在已有
td中嵌套新创建的td,导致DOM结构层级异常 - 最后
tr.append(imageTds, nameTds, ...)是把整个NodeList添加进去,而非单个元素,引发渲染异常
方案优势
- 完全复用已有EJS局部视图代码,无需重复编写DOM拼接逻辑,降低维护成本
- 仅局部更新页面内容,不会刷新整个页面,用户体验更流畅
- 逻辑简洁清晰,避免手动操作DOM带来的各类bug
内容的提问来源于stack exchange,提问作者DabInALab
相关产品推荐
相关产品推荐

