在 <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();
});