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

如何实现点击分类后通过客户端请求重新渲染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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:44:54