为何AJAX提交表单时页面仍刷新?已调用e.preventDefault()
关注/取消关注系统点击按钮页面自动刷新问题
我正在开发一个简易的关注/取消关注系统,数据库的增删操作都正常,但每次点击按钮页面都会刷新,明明已经用了e.preventDefault(),这是怎么回事?
页面HTML结构
<div class="followBtns showFollowDiv"> <form method="POST" action=""> <input type="hidden" value="<?php echo $username; ?>" name="username"> <input type="hidden" value="<?php echo $grabUser['username']; ?>" name="following"> <input type="hidden" value="<?php echo date('Y/m/d H:i:s'); ?>" name="date"> <div id="followButtonContainer"> <?php if ($is_following): ?> <button class="followBtn" type="button" value="unfollow" name="action">Unfollow</button> <?php else: ?> <button class="followBtn" type="button" value="follow" name="action">Follow</button> <?php endif; ?> </div> </form> </div>
前端JavaScript代码
<script type="text/javascript"> //~~~~~~~~~~~~~~~~~~~~ SCRIPT FOR FOLLOWING A USER ~~~~~~~~~~~~~~~~~~~~// $(document).ready(function() { console.log("Follow function is working.."); $(".followBtn").on("click", function(e) { // Prevent the default behavior of the button e.preventDefault(); // Check if the button triggers the login modal if ($(this).hasClass('followBtn-signin')) { $('#loginModal').modal('show'); // Show login modal return; } var followButton = $(this); var formDataFollow = { 'FollowUser': true, 'username': $('input[name="username"]').val(), 'following': $('input[name="following"]').val(), 'date': $('input[name="date"]').val(), 'action': $(this).val() }; console.log(formDataFollow); $.ajax({ type: "POST", url: "/Blog/resources/PHP/FollowUserPHP.php", data: formDataFollow, dataType: 'json', success: function(response) { $('#followButtonContainer').html(response.button); // Toggle the button text based on the response if (response.status === "followed") { // Increment the follower count on the frontend var followerCountElement = $('.follower-count'); followerCountElement.text(parseInt(followerCountElement.text()) + 1); } else if (response.status === "unfollowed") { // Decrement the follower count on the frontend var followerCountElement = $('.follower-count'); followerCountElement.text(parseInt(followerCountElement.text()) - 1); } }, error: function(xhr, status, error) { console.log(error); } }); }); }); </script>
后端PHP代码(FollowUserPHP.php)
<?php session_start(); require_once '/var/www/vhosts/ggweb3.xyz/httpdocs/PHP/connect.php'; if (isset($_POST['username']) && isset($_POST['following']) && isset($_POST['date']) && isset($_POST['action'])) { $username = filter_var($_POST['username'], FILTER_SANITIZE_STRING); $following = filter_var($_POST['following'], FILTER_SANITIZE_STRING); $date = filter_var($_POST['date'], FILTER_SANITIZE_STRING); $action = $_POST['action']; // Check if the user is already following the viewed user $stmt_check = $dbh->prepare("SELECT COUNT(*) AS following_count FROM followers WHERE username = :username AND following = :following"); $stmt_check->bindParam(':username', $username, PDO::PARAM_STR); $stmt_check->bindParam(':following', $following, PDO::PARAM_STR); $stmt_check->execute(); $fetchFollowing = $stmt_check->fetch(); $is_following = ($fetchFollowing['following_count'] > 0); if ($action == 'follow' && !$is_following) { $stmt = $dbh->prepare("INSERT INTO `followers` (`username`, `following`, `date`) VALUES (:username, :following, :date)"); $stmt->bindParam(':username', $username, PDO::PARAM_STR); $stmt->bindParam(':following', $following, PDO::PARAM_STR); $stmt->bindParam(':date', $date, PDO::PARAM_STR); $stmt->execute(); $response = array('status' => 'followed', 'button' => '<button class="followBtn" type="button" value="unfollow" name="action">Unfollow</button>'); } elseif ($action == 'unfollow' && $is_following) { $stmt = $dbh->prepare("DELETE FROM `followers` WHERE `username` = :username AND `following` = :following"); $stmt->bindParam(':username', $username, PDO::PARAM_STR); $stmt->bindParam(':following', $following, PDO::PARAM_STR); $stmt->execute(); $response = array('status' => 'unfollowed', 'button' => '<button class="followBtn" type="button" value="follow" name="action">Follow</button>'); } else { // Invalid action value or user is already following/unfollowing $response = array('error' => 'Invalid action or user is already following/unfollowing'); } } else { // Missing parameters $response = array('error' => 'Missing parameters'); } // Output the response as JSON header('Content-Type: application/json'); echo json_encode($response); exit; ?>
问题原因及解决方案
问题核心在于动态替换按钮后事件绑定失效:
- 初始页面加载时,你给
.followBtn绑定了点击事件,但AJAX成功后,用$('#followButtonContainer').html(response.button)替换了原有按钮,新生成的按钮没有绑定点击事件。此时点击新按钮,虽然type="button"不会直接提交表单,但如果存在其他隐性触发表单提交的逻辑,就会导致页面刷新。
解决方法:使用事件委托绑定事件
把事件绑定到静态存在的父容器上,监听子元素的点击事件,这样动态生成的按钮也能触发逻辑:
$(document).ready(function() { console.log("Follow function is working.."); // 绑定到父容器,监听子元素的点击事件 $("#followButtonContainer").on("click", ".followBtn", function(e) { e.preventDefault(); if ($(this).hasClass('followBtn-signin')) { $('#loginModal').modal('show'); return; } var followButton = $(this); var formDataFollow = { 'FollowUser': true, 'username': $('input[name="username"]').val(), 'following': $('input[name="following"]').val(), 'date': $('input[name="date"]').val(), 'action': $(this).val() }; console.log(formDataFollow); $.ajax({ type: "POST", url: "/Blog/resources/PHP/FollowUserPHP.php", data: formDataFollow, dataType: 'json', success: function(response) { $('#followButtonContainer').html(response.button); if (response.status === "followed") { var followerCountElement = $('.follower-count'); followerCountElement.text(parseInt(followerCountElement.text()) + 1); } else if (response.status === "unfollowed") { var followerCountElement = $('.follower-count'); followerCountElement.text(parseInt(followerCountElement.text()) - 1); } }, error: function(xhr, status, error) { console.log(error); } }); }); });
额外保险:阻止表单默认提交行为
可以给表单添加submit事件监听,彻底防止表单提交导致的页面刷新:
$("form").on("submit", function(e) { e.preventDefault(); });
内容的提问来源于stack exchange,提问作者kbmzeeC0de
相关产品推荐
相关产品推荐

