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

EJS多表单中AJAX点赞功能仅首个生效问题求助

点赞按钮批量触发首个表单问题解决

问题描述

在EJS页面的多篇帖子中设置点赞按钮后,点击首个按钮时表单提交和视图更新正常,但点击其他按钮时,始终触发首个表单的提交,且仅为首个按钮添加active类。改用类名替代ID后问题依旧,数据库更新正常,问题出在AJAX逻辑和HTML结构上。

原代码

HTML

<form id='like' action="/postLike/<%=blogposts[i]._id%>?_method=PATCH" method="POST">
            <% if (blogposts[i].liked == false) {%> 
            <div id='likeBtn' onclick="Like()" class="wrapperHearts">
            <svg xmlns="http://www.w3.org/2000/svg" id="Love"><path d="M28.124,15.5615,16.7549,28.6558a1,1,0,0,1-1.51,0L3.876,15.5615A7.6866,7.6866,0,0,1,2.57,7.61a7.1712,7.1712,0,0,1,6.085-4.5752C8.915,3.0122,9.1768,3,9.4424,3A8.6981,8.6981,0,0,1,16,6.0083,8.6981,8.6981,0,0,1,22.5576,3c.2656,0,.5274.0122.7862.0352A7.1713,7.1713,0,0,1,29.43,7.61,7.6866,7.6866,0,0,1,28.124,15.5615Z" style="fill:#212123"/></svg>
            </div><%}%>
            <% if (blogposts[i].liked == true) {%> 
                <div id='likeBtn' onclick="Like()" class="wrapperHearts active">
                <svg xmlns="http://www.w3.org/2000/svg" id="Love"><path d="M28.124,15.5615,16.7549,28.6558a1,1,0,0,1-1.51,0L3.876,15.5615A7.6866,7.6866,0,0,1,2.57,7.61a7.1712,7.1712,0,0,1,6.085-4.5752C8.915,3.0122,9.1768,3,9.4424,3A8.6981,8.6981,0,0,1,16,6.0083,8.6981,8.6981,0,0,1,22.5576,3c.2656,0,.5274.0122.7862.0352A7.1713,7.1713,0,0,1,29.43,7.61,7.6866,7.6866,0,0,1,28.124,15.5615Z" style="fill:#212123"/></svg>
                </div><%}%>
            </form>

AJAX

let likeButton = document.querySelector('.wrapperHearts');
let frm = $('#like');

function Like(){ frm.submit()}

frm.submit(function (e) {
  e.preventDefault(e);

  var formData = new FormData(this);

  $.ajax({
    async: true,
    type: frm.attr('method'),
    url: frm.attr('action'),
    data: formData,
    processData: false,
    contentType: false,

    success: function (data) {
      console.log("success");
      console.log(data)
      if (data.liked == false){
        likeButton.classList.add('active')
        $("#likesNumber").text(data.likes +1 + ' ' + 'Likes')
      }
      else{
        likeButton.classList.remove('active')
        $("#likesNumber").text(data.likes -1 + ' ' + 'Likes')   
      }
    },
    error: function(request, status, error) {
      console.log("error")
    }
  });
});

问题根源

  1. 重复ID冲突:所有表单和按钮都使用了相同的ID(like、likeBtn),DOM中ID必须唯一,jQuery选择器只会匹配第一个元素。
  2. 全局选择器局限:document.querySelector('.wrapperHearts')和$('#like')仅获取第一个匹配元素,导致所有操作都指向首个帖子的按钮和表单。
  3. 全局函数绑定错误:Like()函数是全局的,调用时始终触发首个表单的提交。
  4. 点赞数选择器不精准:$("#likesNumber")同样只会匹配第一个点赞数容器,无法对应当前操作的帖子。

修复方案

修改后的HTML

移除重复ID,用类名标识元素,并添加点赞数容器:

<form class='like-form' action="/postLike/<%=blogposts[i]._id%>?_method=PATCH" method="POST">
    <% if (blogposts[i].liked == false) {%> 
    <div class="wrapperHearts like-btn">
        <svg xmlns="http://www.w3.org/2000/svg" class="Love-icon"><path d="M28.124,15.5615,16.7549,28.6558a1,1,0,0,1-1.51,0L3.876,15.5615A7.6866,7.6866,0,0,1,2.57,7.61a7.1712,7.1712,0,0,1,6.085-4.5752C8.915,3.0122,9.1768,3,9.4424,3A8.6981,8.6981,0,0,1,16,6.0083,8.6981,8.6981,0,0,1,22.5576,3c.2656,0,.5274.0122.7862.0352A7.1713,7.1713,0,0,1,29.43,7.61,7.6866,7.6866,0,0,1,28.124,15.5615Z" style="fill:#212123"/></svg>
    </div><%}%>
    <% if (blogposts[i].liked == true) {%> 
    <div class="wrapperHearts like-btn active">
        <svg xmlns="http://www.w3.org/2000/svg" class="Love-icon"><path d="M28.124,15.5615,16.7549,28.6558a1,1,0,0,1-1.51,0L3.876,15.5615A7.6866,7.6866,0,0,1,2.57,7.61a7.1712,7.1712,0,0,1,6.085-4.5752C8.915,3.0122,9.1768,3,9.4424,3A8.6981,8.6981,0,0,1,16,6.0083,8.6981,8.6981,0,0,1,22.5576,3c.2656,0,.5274.0122.7862.0352A7.1713,7.1713,0,0,1,29.43,7.61,7.6866,7.6866,0,0,1,28.124,15.5615Z" style="fill:#212123"/></svg>
    </div><%}%>
    <div class="likes-number"><%= blogposts[i].likes %> Likes</div>
</form>

修改后的AJAX

使用事件委托绑定点击事件,通过相对DOM查找定位当前操作的元素:

// 事件委托绑定所有点赞按钮
$(document).on('click', '.like-btn', function() {
    const $btn = $(this);
    const $form = $btn.closest('.like-form');
    const $likesNumber = $form.find('.likes-number');

    $.ajax({
        async: true,
        type: $form.attr('method'),
        url: $form.attr('action'),
        data: new FormData($form[0]),
        processData: false,
        contentType: false,
        success: function(data) {
            console.log("success");
            console.log(data);
            // 更新按钮状态和点赞数
            if (data.liked) {
                $btn.addClass('active');
            } else {
                $btn.removeClass('active');
            }
            $likesNumber.text(data.likes + ' Likes');
        },
        error: function(request, status, error) {
            console.log("error");
        }
    });
});

核心修改说明

  • 移除重复ID:所有元素改用类名,避免DOM唯一性冲突。
  • 事件委托:确保动态生成的帖子按钮也能触发事件。
  • 相对DOM查找:通过closest()和find()精准定位当前按钮对应的表单和点赞数容器,不再操作全局第一个元素。
  • 去掉全局函数:直接在点击事件中处理AJAX逻辑,避免全局绑定错误。

内容的提问来源于stack exchange,提问作者CristianMihai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 02:01:13