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

Laravel 8中如何阻止Ajax加载表单的默认提交行为?

问题背景

我在Laravel 8中开发了一款博客应用,目前正在通过jQuery(v3.5.0)AJAX实现评论回复功能。

评论表单模板(comment-form.blade.php)

<div class="form-wrapper">
  <div class="alert-box-ajax alert-box alert-box--success">
    Your comment is pending
  </div>

  <div class="alert-box-ajax alert-box alert-box--error">
    Failed to add comment!
  </div>

  <form class="commentForm" method="post" action="{{ route('comment.submit') }}" autocomplete="off" novalidate>
    @csrf
      <fieldset>
        <input type="hidden" name="article_id" value="{{ isset($article->id) ? $article->id : $article_id }}">
        <input type="hidden" name="parent_id" value="{{ $comment->id ?? '' }}">

        <div class="message form-field">
            <textarea name="msg" id="message" class="h-full-width" placeholder="Your Message" required></textarea>

            @error('msg')
            <p class="help-block text-danger">{{ $message }}</p>
            @enderror
        </div>
        <br>
        <input name="submit" id="submit" class="btn btn--primary btn-wide btn--large h-full-width" value="Add Comment" type="submit">
      </fieldset>
  </form>
</div>

该模板会为每条评论重复渲染,以便对任意评论添加回复。

AJAX提交代码

$(".commentForm").each(function () {
    var form = $(this);
    form.validate({
        errorElement: "p",
        errorClass: "help-block text-danger",

        submitHandler: function (_form, event) {
            event.preventDefault();
            var $fields = form.find("textarea"),
                url = form.attr("action"),
                data = form.serialize();
            $.ajax({
                dataType: "json",
                type: "post",
                url: url,
                data: data,
                cache: false,
                success: function (response) {
                  if (response.status === 'success') {
                    form.closest(".form-wrapper").find(".alert-box--success").slideDown(250).delay(2500).slideUp(250)
                        .slideDown(250)
                        .delay(2500)
                        .slideUp(250);
                  $fields.val("");
                  } else {
                    form.closest(".form-wrapper").find(".alert-box--error").slideDown(250).delay(2500).slideUp(250)
                        .slideDown(250)
                        .delay(2500)
                        .slideUp(250);
                  }
                },
                error: function (err) {    
                  console.log(err);
                },
            });
        },
    });
});

问题描述

应用设置为单篇文章初始最多加载10条评论,剩余评论通过页面滚动触发Ajax加载。启用该功能后,上述脚本无法阻止通过Ajax加载的表单的默认提交行为。

注意: 问题并非提交事件本身,而是无法阻止其默认行为。

疑问

  1. 该问题的成因是什么?
  2. 最可靠的解决方案是什么?

问题成因

当前代码仅在页面初始加载时,对已存在的.commentForm元素绑定验证和提交逻辑。但通过AJAX动态加载的评论表单是在初始页面渲染后才添加到DOM中的,这些新元素没有被绑定validate方法,提交时不会触发自定义的submitHandler,因此无法阻止默认提交行为。

解决方案

推荐两种可靠方案:

方案1:事件委托+手动验证(高效简洁)

放弃对单个表单绑定validate,改用事件委托监听所有.commentForm的提交事件,手动触发验证后执行AJAX提交:

// 绑定到评论列表的父容器(需替换为实际的父容器选择器,比如#comments-list)
$("#comments-list").on("submit", ".commentForm", function(event) {
    event.preventDefault();
    var form = $(this);
    
    // 手动触发验证,不通过则终止
    if (!form.valid()) return;
    
    // 执行AJAX提交逻辑
    var $fields = form.find("textarea"),
        url = form.attr("action"),
        data = form.serialize();
        
    $.ajax({
        dataType: "json",
        type: "post",
        url: url,
        data: data,
        cache: false,
        success: function (response) {
            if (response.status === 'success') {
                form.closest(".form-wrapper").find(".alert-box--success")
                    .slideDown(250).delay(2500).slideUp(250)
                    .slideDown(250).delay(2500).slideUp(250);
                $fields.val("");
            } else {
                form.closest(".form-wrapper").find(".alert-box--error")
                    .slideDown(250).delay(2500).slideUp(250)
                    .slideDown(250).delay(2500).slideUp(250);
            }
        },
        error: function (err) {    
            console.log(err);
        },
    });
});

// 初始化所有初始表单的验证规则
$(".commentForm").validate({
    errorElement: "p",
    errorClass: "help-block text-danger"
});

无论初始还是动态加载的表单,提交事件都会被父容器捕获处理,同时保留jQuery Validate的验证能力。

方案2:动态加载后重新初始化验证

封装初始化逻辑为函数,在页面加载和动态加载评论完成后都调用:

// 封装初始化函数,标记已初始化避免重复绑定
function initCommentForms() {
    $(".commentForm").not(".initialized").each(function () {
        var form = $(this);
        form.addClass("initialized");
        form.validate({
            errorElement: "p",
            errorClass: "help-block text-danger",
            submitHandler: function (_form, event) {
                event.preventDefault();
                var $fields = form.find("textarea"),
                    url = form.attr("action"),
                    data = form.serialize();
                $.ajax({
                    dataType: "json",
                    type: "post",
                    url: url,
                    data: data,
                    cache: false,
                    success: function (response) {
                        if (response.status === 'success') {
                            form.closest(".form-wrapper").find(".alert-box--success")
                                .slideDown(250).delay(2500).slideUp(250)
                                .slideDown(250).delay(2500).slideUp(250);
                            $fields.val("");
                        } else {
                            form.closest(".form-wrapper").find(".alert-box--error")
                                .slideDown(250).delay(2500).slideUp(250)
                                .slideDown(250).delay(2500).slideUp(250);
                        }
                    },
                    error: function (err) {    
                        console.log(err);
                    },
                });
            },
        });
    });
}

// 页面初始加载时初始化
$(document).ready(function() {
    initCommentForms();
});

// 在加载更多评论的AJAX成功回调中调用初始化
$.ajax({
    // 加载更多评论的配置
    success: function(response) {
        // 插入新评论到DOM
        $("#comments-list").append(response.html);
        // 初始化新表单
        initCommentForms();
    }
});

通过标记已初始化的表单,确保动态加载的表单也能获得完整的验证和AJAX提交逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 20:52:15