如何实现点击分类后通过客户端请求重新渲染EJS页面?
解决方案:点击分类刷新/更新页面内容
方案一:页面刷新式(简单直接)
这种方案通过跳转页面并携带查询参数,让服务端重新渲染整个页面,适合不需要无刷新交互的场景。
1. 修改EJS中的<a>标签
给每个分类链接添加href属性,携带选中的分类名称作为查询参数:
<div> <% namesArr.forEach(name => { %> <a class="other-categories" href="/?selected=<%= encodeURIComponent(name) %>" data-doc="<%= name %>" id="<%= name %>"> <%= name %> </a> <% }); %> </div>
encodeURIComponent用于处理带空格的分类名称,避免URL解析错误。
2. 服务端路由处理(Express+Mongoose)
修改首页路由,接收查询参数selected,根据它获取对应分类的图片数组:
app.get('/', async (req, res) => { try { // 获取所有分类数据 const allCategories = await Category.find(); const namesArr = allCategories.map(category => category.name); // 获取选中的分类,默认取第一个分类(如果没有传参数) const selectedName = req.query.selected || namesArr[0]; // 根据选中名称查询对应分类的图片数组 const targetCategory = await Category.findOne({ name: selectedName }); const imgArr = targetCategory ? targetCategory.imgs : []; // 渲染页面,传递更新后的参数 res.render('index', { selectedName, namesArr, imgArr }); } catch (err) { console.error(err); res.status(500).send('服务器出错'); } });
用async/await替代Promise链式调用,代码更简洁易读。
方案二:无刷新式(AJAX/fetch)
如果想要更好的用户体验,不需要整页刷新,可以用fetch请求API接口,动态更新页面内容。
1. 服务端新增API接口
添加一个专门返回分类数据的接口:
app.get('/api/category', async (req, res) => { try { const selectedName = req.query.name; if (!selectedName) { return res.status(400).json({ error: '缺少分类名称参数' }); } const targetCategory = await Category.findOne({ name: selectedName }); if (!targetCategory) { return res.status(404).json({ error: '分类不存在' }); } // 返回需要的数据 res.json({ selectedName, imgArr: targetCategory.imgs }); } catch (err) { console.error(err); res.status(500).json({ error: '服务器出错' }); } });
2. 客户端JS处理点击事件
修改点击事件,通过fetch请求API,然后动态更新DOM:
const otherCategories = document.querySelectorAll('.other-categories'); // 假设图片容器有这个类,方便选择 const imgContainer = document.querySelector('.img-container'); otherCategories.forEach(category => { category.addEventListener('click', async function(e) { e.preventDefault(); // 阻止a标签默认跳转行为 const selectedName = this.dataset.doc; try { // 发送请求,携带分类名称参数 const response = await fetch(`/api/category?name=${encodeURIComponent(selectedName)}`); const data = await response.json(); // 清空现有图片,重新渲染 imgContainer.innerHTML = ''; data.imgArr.forEach(img => { const imgElement = document.createElement('img'); imgElement.src = `/imgs/${encodeURIComponent(data.selectedName)}/${img}`; imgContainer.appendChild(imgElement); }); // 可选:给选中的分类添加高亮样式 otherCategories.forEach(item => item.classList.remove('active')); this.classList.add('active'); } catch (err) { console.error(err); } }); });
3. 修改EJS的图片容器
给图片容器添加类名,方便JS选择:
<div class="img-container"> <% imgArr.forEach(img => { %> <img src="/imgs/<%= encodeURIComponent(selectedName) %>/<%= img %>"> <% }) %> </div>
两种方案对比
- 方案一:实现简单,不需要额外处理DOM更新,适合对用户体验要求不高的场景。
- 方案二:无刷新更新内容,用户体验更好,但需要额外编写API接口和DOM更新逻辑。
内容的提问来源于stack exchange,提问作者avocadoPuff
相关产品推荐
相关产品推荐

