AJAX AJAX 响应表单上的无限 preventDefault()(vanilla JS)

AJAX infinite preventDefault() on AJAX-responded form (vanilla JS)

一路上我审阅了几个很棒的问题,数量之多以至于我在一天内获得了 40 票的徽章。但是,几乎所有问题都使用像 jQuery 这样的非 Vanilla 依赖项,或者没有解决我的特定需求。这里有两个精彩的例子,但与我的悲伤无关,问题:

我很惊讶这个问题没有被问到,因为我不认为自己如此富有想象力。如果这个问题已经存在,我想请您打开一个关于如何更新该问题的元讨论,以便搜索可以找到它。

情况:

这是 Vanilla JS,没有依赖项。

该脚本使用 preventDefault() 中断由 id 标识的 form-submit 按钮并改为调用 AJAX。 AJAX 可以正常工作并正确更改内容。那么,问题就开始了...

此 AJAX 以替换的 div 响应,其中包含与 preventDefault() 中断相同的 form。但是,AJAX 无法识别在 AJAX 响应后更新的 form-submit 按钮 JS 更改包含 formdiv同样的 id.

工作流程:

  1. HTML -> <form id="same">(成功)
  2. <form id="same"> -> AJAX(成功,第一个 AJAX 调用)
  3. AJAX -> <form id="same">(成功,第一个 AJAX 响应)
  4. <form id="same"> -> AJAX(损坏,第二个 AJAX 调用)

仅在第一次有效;我需要它无限工作。

注意,我需要处理这个特定的 form。 AJAX 更改的 div 中可能包含其他元素,包括可能的其他形式。

代码:

index.php:

(AJAX 改编自 MDN - Sending forms through JavaScript: Using FormData bound to a form element)

  <script>
  window.addEventListener( "load", function () {
    function sendData() {
      const AJAX = new XMLHttpRequest(); // AJAX handler
      const FD = new FormData( form ); // Bind to-send data to form element

      AJAX.addEventListener( "load", function(event) {
        document.getElementById("ajax_changes").innerHTML = event.target.responseText;
      } ); // Change HTML on successful response
      AJAX.addEventListener( "error", function( event ) {
        document.getElementById("ajax_changes").innerHTML =  'Oops! Something went wrong.';
      } );
      AJAX.open( "POST", "ajax_responder.php" ); // Send data, ajax_responder.php can be any file or URL
      AJAX.send( FD ); // Data sent is from the form

    } // sendData() function

    const form = document.getElementById( "ajaxForm" ); // Access <form id="ajaxForm">, id="ajaxForm" can be anything
    form.addEventListener( "submit", function ( event ) { // Takeover <input type="submit">
      event.preventDefault();
      sendData();
    } );

  } );
  </script>

  <div id="ajax_changes">Replace me with AJAX<br>
    <form id="ajaxForm">
      <input type="text" value="AJAX" name="foo">
      <input type="text" value="5" name="bar">
      <input type="submit" value="Form AJAX!">
    </form>
  <!-- Possible other HTML elements and/or forms I do not want to process with that same AJAX -->
  </div>

ajax_responder.php :

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  $foo = $_POST['foo'];
  $bar = $_POST['bar'];

echo '
'.$foo.'
<br>
'.$bar.'
<br>
<form id="ajaxForm">
  <input type="text" value="'.$foo.'" name="foo">
  <input type="text" value="'.$bar.'" name="bar">
  <input type="submit" value="Form AJAX!">
</form>
<!-- Possible other HTML elements and/or forms -->
';
}

问题

让 AJAX 继续作用于相同的包含响应的 form-submit 元素的“正确”方法是什么?

我已经考虑过不响应的方式 form:

但这两个看起来都很复杂。

必须有一些方法可以在 form-submit 按钮 之后 告诉 AJAX 到 preventDefault() AJAX 已更新。我只是不知道那是什么。

或者,还有其他解决方案仍然涉及 Vanilla JS 吗?

您正在将 eventListener 绑定到 <form> ajaxForm。然后替换它(= 从 DOM 中删除 <form> 并将新的 <form> 添加到 DOM 中)。在这种情况下,eventListener 也会被删除。

要在新表单上使用 eventListener,您可以:

• 仅替换 <form> 的内容。在这种情况下,DOM 元素不会被删除,因此 eventListener 保持不变 (不要忘记删除 php 响应中的 <form> 标签)。恕我直言,这是最简单的方法。

document.getElementById("ajaxForm").innerHTML=
                             event.target.responseText;

• 每次 <form> 更改时绑定一个新的 eventListener:

AJAX.addEventListener( "load", function(event) {
        document.getElementById("ajax_changes").innerHTML =
                             event.target.responseText;
//=====> bind new eventListener here <======
      } );

您可以创建一个可以在 ajax 响应

中加载时调用的函数
function addListenerToForm(){
    document.getElementById( "ajaxForm" ).addEventListener( "submit", function ( event ) {
       event.preventDefault();
       sendData();
    });
  }

• 将 eventListener 绑定一次到容器 <div>

document.getElementById( "ajax_changes" ).addEventListener( "submit", function ( event ) {
  event.preventDefault();
  sendData();
});

function sendData(){
   const AJAX = new XMLHttpRequest(); // AJAX handler
   const form = document.getElementById( "ajaxForm");               
   const FD = new FormData( form );
   ...
   }

鉴于 的解决方案 “每次 <form> 更改时绑定一个新的 eventListener”,

我改了const

const form = document.getElementById( "ajaxForm" );

var

var form = document.getElementById( "ajaxForm" );

然后把它和它的监听器放在这一行

//=====> bind new eventListener here <======

没有任何声明为

form = document.getElementById( "ajaxForm" );
  form.addEventListener( "submit", function ( event ) {...

而且成功了!非常感谢!我是一个快乐的编程土豆。

我的新 JavaScript 是:

  <script>
  window.addEventListener( "load", function () {
    function sendData() {
      const AJAX = new XMLHttpRequest(); // AJAX handler
      const FD = new FormData( form ); // Bind to-send data to form element

      AJAX.addEventListener( "load", function(event) {
        document.getElementById("ajax_changes").innerHTML = event.target.responseText;
      } ); // Change HTML on successful response

      AJAX.addEventListener( "error", function( event ) {
        document.getElementById("ajax_changes").innerHTML =  'Oops! Something went wrong.';
      } );

      AJAX.open( "POST", "ajax_responder.php" ); // Send data, ajax_responder.php can be any file or URL

      AJAX.send( FD ); // Data sent is from the form

      AJAX.addEventListener( "load", function(event) {
        document.getElementById("ajax_changes").innerHTML =
          event.target.responseText;
          // Bind a new eventListener everytime the <form> is changed:
          form = document.getElementById( "ajaxForm" ); // Access <form id="ajaxForm">, id="ajaxForm" can be anything
          form.addEventListener( "submit", function ( event ) { // Takeover <input type="submit">
            event.preventDefault();
            sendData();
          } ); // End new event listener
      } );
    } // sendData() function

    var form = document.getElementById( "ajaxForm" ); // Access <form id="ajaxForm">, id="ajaxForm" can be anything
    form.addEventListener( "submit", function ( event ) { // Takeover <input type="submit">
      event.preventDefault();
      sendData();
    } );

  } );
  </script>