jQuery无法绑定动态评论的回复事件,求正确选择器配置
解决动态生成评论无法回复的问题
看起来你遇到的核心问题是动态生成的评论无法触发回复功能,主要源于两个关键问题:重复的DOM ID导致模态框失效,以及事件没有绑定到动态元素上。下面一步步帮你解决:
1. 先修复最致命的重复ID问题
你的当前代码里,每个评论模板都包含一个id="replyModal"的模态框,但HTML中ID必须是全局唯一的!这会导致只有第一个评论的模态框能正常工作,动态生成的评论的模态框根本无法被浏览器正确识别和触发。
修正方案:把模态框抽成全局唯一的
把模态框从评论模板里移出来,放到页面的全局位置(比如页面底部,所有评论列表之外),只保留一个:
<!-- 全局唯一的回复模态框,放到页面底部 --> <div class="modal fade" id="replyModal" tabindex="-1" role="dialog" aria-labelledby="replyModalLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="replyModalLabel">Submit Feedback</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <form id="send-reply-form" asp-action="AddReply" asp-controller="Business" asp-area="Business"> <input type="hidden" name="feedbackparentId" id="feedbackparentId"/> <input type="hidden" name="businessid" value="@Model.Business.Id" /> @Html.AntiForgeryToken() <div class="form-group form-inline"> <div class="form-group col-lg-6 col-md-6 name"> <input type="text" name="authorName" class="form-control col-form-label" id="name" placeholder="Enter Name" onfocus="this.placeholder = ''" onblur="this.placeholder = 'Enter Name'"> </div> <div class="form-group col-lg-6 col-md-6 email"> <input type="email" name="email" class="form-control" id="email" placeholder="Enter email address" onfocus="this.placeholder = ''" onblur="this.placeholder = 'Enter email address'"> </div> </div> <div class="form-group"> <textarea class="form-control mb-10" rows="5" name="comment" placeholder="Message" onfocus="this.placeholder = ''" onblur="this.placeholder = 'Message'" required=""></textarea> </div> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> <button type="submit" class="btn btn-primary">Send Feedback</button> </form> </div> </div> </div> </div>
然后修改评论模板,移除里面的模态框,只保留回复按钮(注意把按钮的ID改成类名,避免重复ID):
@model FeedbackViewModel <div class="comment-list"> <div class="single-comment justify-content-between d-flex feedbackCom"> <div class="user justify-content-between d-flex"> <div class="thumb"> <img src="~/images/blog/c3.jpg" alt=""> </div> <div class="desc"> <h5> <a href="#">@Model.Name</a> </h5> <p class="date">@Model.CreatedOn.Value.ToLongDateString()</p> <p class="comment"> @Model.Comment </p> </div> </div> <div class="reply-btn"> <!-- 用类名代替ID,避免重复 --> <button class="btn btn-primary float-right reply-button" type="button" data-toggle="modal" data-target="#replyModal" data-id="@Model.Id">Reply</button> </div> </div> </div> <div class="comment-list left-padding" id="@Model.Id"> @foreach (var reply in Model.Replies.OrderByDescending(r => r.CreatedOn)) { <partial name="_ReplySectionPartial" model="reply" /> } </div>
2. 用事件委托绑定动态元素的点击事件
动态生成的评论在页面初始加载时不存在,所以不能直接给它们的回复按钮绑定click事件。我们需要用事件委托——把事件绑定到一个始终存在的父元素上(比如.comment-list),由它来监听子元素的点击。
同时,点击回复按钮时要把当前评论的ID赋值给表单的隐藏字段,这样提交回复时才能正确关联父评论。
3. 修正JavaScript代码
更新你的JS代码,添加事件委托逻辑,同时优化表单提交的处理:
$(function () { const $replyForm = $('#send-reply-form'); const $replyModal = $('#replyModal'); const $feedbackParentIdInput = $('#feedbackparentId'); // 事件委托:处理所有回复按钮的点击(包括动态生成的) $('.comment-list').on('click', '.reply-button', function() { const feedbackId = $(this).data('id'); // 将父评论ID赋值给表单的隐藏字段 $feedbackParentIdInput.val(feedbackId); }); // 表单提交逻辑(保留原逻辑,优化ID获取方式) $replyForm.on('submit', function (event) { event.preventDefault(); const dataToSend = $replyForm.serialize(); const feedbackId = $feedbackParentIdInput.val(); const feedbackParentElement = $('#' + feedbackId); $.post($replyForm.attr('action'), dataToSend, function (serverData) { $('#send-reply-form')[0].reset(); // 清空隐藏字段,避免下次回复带旧ID $feedbackParentIdInput.val(''); $(feedbackParentElement).prepend(serverData); // 提交后自动关闭模态框 $replyModal.modal('hide'); }) }) })
为什么之前的代码不生效?
- 重复ID冲突:每个评论都有相同ID的模态框和回复按钮,浏览器只能识别第一个,动态生成的元素无法触发响应。
- 事件绑定范围问题:初始代码直接绑定到静态DOM元素上,动态生成的元素没有被绑定事件。
- 父ID传递缺失:之前的代码没有在点击回复按钮时把评论ID传入表单,导致提交时无法关联正确的父评论。
这样修改后,不管是页面加载时的初始评论,还是动态生成的新评论,都能正常触发回复功能了。
内容的提问来源于stack exchange,提问作者Tihomir Todorov
相关产品推荐
相关产品推荐

