点击按钮无法触发Ajax,但下拉框onchange可触发的问题排查
问题
我是Ajax新手,现有一个包含表单的PHP文件,希望点击提交按钮后,通过Ajax将表单数据发送至另一个PHP文件处理(该过程可能耗时较长),处理完成后返回结果至原PHP文件。以下是我的代码:
<html> <head> <script src="jquery.min.js"></script> <script> function submitBorrow() { // Call to the 'ajax' function $.ajax({ type: "POST", url: "sendEmail.php", data: { test:'yes', wat:'no' }, success: function(html) { $("#emailResultDiv").html(html); } }); } </script> </head> <body> <form id="borrowForm" name="borrowForm"> <select name="duration" id="duration" onchange="submitBorrow();"> <option value="3 days">3 days</option> <option value="4 days">4 days</option> <option value="5 days">5 days</option> <option value="6 days">6 days</option> <option value="1 week">7 days</option> <option value="2 week">14 days</option> <option value="3 week">21 days</option> <option value="1 month">30 days</option> <option value="40 days">40 days</option> <option value="60 days">60 days</option> </select> <button onclick="submitBorrow();">submitBorrow</button> <div id="emailResultDiv">Here</div> </form> </body> </html>
sendEmail.php内容如下:
<?php if ($_POST) { sleep(5); echo "DONE!"; } ?>
当下拉框选项改变时,5秒后div会显示“DONE!”,但点击按钮时却无此效果,请问原因是什么?该如何实现需求?
原因分析
按钮位于<form>标签内,默认类型是submit,点击后会触发表单的默认提交行为——页面会立即刷新。这会中断正在进行的Ajax请求,导致请求还没完成就被页面刷新终止,自然看不到返回的结果。而下拉框的onchange事件不会触发表单默认提交,所以Ajax请求能正常完成。
解决方法
有三种常用方案可以解决这个问题:
方案1:修改按钮类型为button
给按钮添加type="button"属性,明确它不是提交按钮,就不会触发表单默认提交:
<button type="button" onclick="submitBorrow();">submitBorrow</button>
方案2:阻止按钮点击的默认行为
在onclick事件中返回false,或者在函数内阻止事件默认行为:
- 方式A:直接在onclick里加return false
<button onclick="submitBorrow(); return false;">submitBorrow</button>
- 方式B:在函数内处理事件
修改JavaScript函数,接收事件参数并阻止默认行为:
function submitBorrow(event) { // 阻止默认行为 event.preventDefault(); $.ajax({ type: "POST", url: "sendEmail.php", data: { test:'yes', wat:'no' }, success: function(html) { $("#emailResultDiv").html(html); } }); }
对应的按钮要传递事件参数:
<button onclick="submitBorrow(event);">submitBorrow</button>
方案3:监听表单submit事件(更规范的写法)
绑定表单的submit事件,阻止默认提交后再执行Ajax,同时可以统一处理下拉框和按钮的提交逻辑:
<script> $(function() { $("#borrowForm").on("submit", function(event) { // 阻止表单默认提交 event.preventDefault(); $.ajax({ type: "POST", url: "sendEmail.php", data: { test:'yes', wat:'no' }, success: function(html) { $("#emailResultDiv").html(html); } }); }); // 下拉框改变时触发表单提交 $("#duration").on("change", function() { $("#borrowForm").submit(); }); }); </script>
然后按钮可以改成标准的提交按钮,不用写onclick:
<button type="submit">submitBorrow</button>
额外优化建议
- 可以在Ajax请求发起时,给
emailResultDiv显示“处理中...”的提示,提升用户体验:
success: function(html) { $("#emailResultDiv").html(html); }, beforeSend: function() { $("#emailResultDiv").html("处理中,请稍候..."); }
- 如果要发送表单的真实数据,不要手动写
data,可以用$(this).serialize()来序列化表单数据,更高效:
data: $("#borrowForm").serialize(),
内容的提问来源于stack exchange,提问作者GeneCode
相关产品推荐
相关产品推荐

