在 <form> 中嵌套 <button> 会导致意外行为
nesting <button> inside <form> causes unexpected behavior
我正在为我的网站使用 ZURB Foundation 6.4(ZURB 模板)。
我想测试我新实现的后端并尝试收集一些输入并通过 jquery AJAX 将其发送到我的 php 后端。
同时,我已经设法做到了,但是我遇到了一个很奇怪的问题。
我使用了以下构建块:
https://foundation.zurb.com/building-blocks/blocks/floated-label-wrapper.html
我稍微修改了一下,但只是关于 id 和占位符之类的东西,没有任何功能。
最后,我将此标记用作我生成的其中一个视图的一部分:
<form class="callout text-center">
<h2>Become A Member</h2>
<div class="floated-label-wrapper">
<label for="full-name">Forename</label>
<input type="text" id="forenameInput" name="forename input" placeholder="forename">
</div>
<div class="floated-label-wrapper">
<label for="email">Surname</label>
<input type="text" id="surnameInput" name="surname input" placeholder="surname">
</div>
<div class="floated-label-wrapper">
<label for="pass">Email</label>
<input type="email" id="emailInput" name="email input" placeholder="email">
</div>
<button class="button expanded" id="submitUserDataButton">Sign up</button>
</form>
最后的按钮曾经是提交类型的输入,我已将其更改为按钮,因为它更适合我的需要。
但是,只要 button/input 嵌套在表单元素内,输入和按钮的行为始终相同:
点击后,网站会重新加载,调用的函数会执行,直到它点击我的 ajax。
现在为了完整起见,我将在这里 post AJAX(它被另一个函数 intp/called 包裹,但这在这里无关紧要):
function sendUserDataToBackend(userDataInputCollection){
console.log("sendUserDataToBackend was entered")
return $.post("http://localhost:8099/test2.php"
}).then((response) => {
console.log(response)
})
}
它进入了函数,console.log 发生了,然后……什么也没有。 AJAX 本身从未执行过。
我真的不知道为什么会这样,我只是想出了如何规避它。
我只是将按钮放在表单元素之外,一切正常。
现在,这是为什么呢?
为什么将按钮嵌套在表单元素中会导致这样的麻烦,比如导致页面重新加载甚至阻止 AJAX 调用的发生?
我的意思是,表单是用来接受输入并将其发送到后端的,不是吗?或者它们以某种方式 "gotten old" 并且应该避免使用它们?
这些元素是如何工作的,它们是什么 "side effects"?
编辑:
这是请求的处理程序代码
处理程序的逻辑是从文件 A 导出的
export async function executeRegistration(){
let userDataInputCollection = getUserDataInput()
userDataInputCollection = JSON.stringify(userDataInputCollection)
console.log(userDataInputCollection)
await sendUserDataToBackend(userDataInputCollection)
}
function getUserDataInput(){
let userDataForename = $('#forenameInput').val()
let userDataSurname = $('#surnameInput').val()
let userDataMail = $('#emailInput').val()
let userDataInputCollection = {
forename : userDataForename,
surname : userDataSurname,
email : userDataMail
}
return userDataInputCollection
}
function sendUserDataToBackend(userDataInputCollection){
console.log("sendUserDataToBackend was entered")
return $.post("http://localhost:8099/test2.php", {
userDataInputCollection : userDataInputCollection
}).then((response) => {
console.log(response)
})
}
并导入到文件 B,通过 jquery:
附加到文件 B
import * as registrationJS from "./lib/registrationLogic.js"
$('#submitUserDataButton').on('click', function(){
registrationJS.executeRegistration()
})
单击提交按钮将提交表单。 这就是提交按钮的意义所在!。
浏览器将离开页面(并加载新页面)。 JavaScript 运行在老页面会被取消(因为JS在页面运行,离开页面退出程序)
如果您想使用Ajax而不是常规表单提交,那么您需要阻止常规表单提交。
请注意,最佳做法也是绑定到表单的提交事件而不是按钮的点击事件。这样可以更好地捕获不使用按钮触发的表单提交。
替换:
$('#submitUserDataButton').on('click', function(){
registrationJS.executeRegistration()
})
与:
$('form').on("submit", function (event) {
event.preventDefault();
registrationJS.executeRegistration();
});
我正在为我的网站使用 ZURB Foundation 6.4(ZURB 模板)。 我想测试我新实现的后端并尝试收集一些输入并通过 jquery AJAX 将其发送到我的 php 后端。
同时,我已经设法做到了,但是我遇到了一个很奇怪的问题。 我使用了以下构建块: https://foundation.zurb.com/building-blocks/blocks/floated-label-wrapper.html
我稍微修改了一下,但只是关于 id 和占位符之类的东西,没有任何功能。 最后,我将此标记用作我生成的其中一个视图的一部分:
<form class="callout text-center">
<h2>Become A Member</h2>
<div class="floated-label-wrapper">
<label for="full-name">Forename</label>
<input type="text" id="forenameInput" name="forename input" placeholder="forename">
</div>
<div class="floated-label-wrapper">
<label for="email">Surname</label>
<input type="text" id="surnameInput" name="surname input" placeholder="surname">
</div>
<div class="floated-label-wrapper">
<label for="pass">Email</label>
<input type="email" id="emailInput" name="email input" placeholder="email">
</div>
<button class="button expanded" id="submitUserDataButton">Sign up</button>
</form>
最后的按钮曾经是提交类型的输入,我已将其更改为按钮,因为它更适合我的需要。 但是,只要 button/input 嵌套在表单元素内,输入和按钮的行为始终相同:
点击后,网站会重新加载,调用的函数会执行,直到它点击我的 ajax。 现在为了完整起见,我将在这里 post AJAX(它被另一个函数 intp/called 包裹,但这在这里无关紧要):
function sendUserDataToBackend(userDataInputCollection){
console.log("sendUserDataToBackend was entered")
return $.post("http://localhost:8099/test2.php"
}).then((response) => {
console.log(response)
})
}
它进入了函数,console.log 发生了,然后……什么也没有。 AJAX 本身从未执行过。 我真的不知道为什么会这样,我只是想出了如何规避它。 我只是将按钮放在表单元素之外,一切正常。
现在,这是为什么呢? 为什么将按钮嵌套在表单元素中会导致这样的麻烦,比如导致页面重新加载甚至阻止 AJAX 调用的发生? 我的意思是,表单是用来接受输入并将其发送到后端的,不是吗?或者它们以某种方式 "gotten old" 并且应该避免使用它们? 这些元素是如何工作的,它们是什么 "side effects"?
编辑: 这是请求的处理程序代码
处理程序的逻辑是从文件 A 导出的
export async function executeRegistration(){
let userDataInputCollection = getUserDataInput()
userDataInputCollection = JSON.stringify(userDataInputCollection)
console.log(userDataInputCollection)
await sendUserDataToBackend(userDataInputCollection)
}
function getUserDataInput(){
let userDataForename = $('#forenameInput').val()
let userDataSurname = $('#surnameInput').val()
let userDataMail = $('#emailInput').val()
let userDataInputCollection = {
forename : userDataForename,
surname : userDataSurname,
email : userDataMail
}
return userDataInputCollection
}
function sendUserDataToBackend(userDataInputCollection){
console.log("sendUserDataToBackend was entered")
return $.post("http://localhost:8099/test2.php", {
userDataInputCollection : userDataInputCollection
}).then((response) => {
console.log(response)
})
}
并导入到文件 B,通过 jquery:
附加到文件 Bimport * as registrationJS from "./lib/registrationLogic.js"
$('#submitUserDataButton').on('click', function(){
registrationJS.executeRegistration()
})
单击提交按钮将提交表单。 这就是提交按钮的意义所在!。
浏览器将离开页面(并加载新页面)。 JavaScript 运行在老页面会被取消(因为JS在页面运行,离开页面退出程序)
如果您想使用Ajax而不是常规表单提交,那么您需要阻止常规表单提交。
请注意,最佳做法也是绑定到表单的提交事件而不是按钮的点击事件。这样可以更好地捕获不使用按钮触发的表单提交。
替换:
$('#submitUserDataButton').on('click', function(){ registrationJS.executeRegistration() })
与:
$('form').on("submit", function (event) {
event.preventDefault();
registrationJS.executeRegistration();
});