【发布时间】:2020-06-30 07:09:20
【问题描述】:
在此过程中,我回顾了几个很棒的问题,以至于我在一天内获得了 40 票的徽章。但是,几乎所有的问题都使用像 jQuery 这样的非 Vanilla 依赖项,或者没有解决我的特定需求。这里有两个很好的例子,但与我的悲伤无关,问题:
-
Ajax Form submit with preventDefault (jQuery)
-
preventDefault() on $.ajax complete(jQuery,以及它的 dup dups 朝圣之旅)
我很惊讶这个问题没有被问到,因为我认为自己没有那么有想象力。如果这个问题已经存在,我想请打开一个关于如何更新该问题以便搜索可以找到它的元讨论。
情况:
这是 Vanilla JS,没有依赖项。
脚本使用preventDefault() 来中断form-submit 由id 标识的按钮,并改为调用AJAX。 AJAX 可以正常工作并正确更改内容。然后,问题就开始了……
此 AJAX 以替换的 div 响应,其中包含 preventDefault() 中断的相同 form。但是,AJAX 无法识别更新后的 form-submit 按钮,在 AJAX 响应 JS 之后,将包含 form 的 div 更改为相同的 id。
工作流程:
- HTML ->
<form id="same">(成功) -
<form id="same">-> AJAX(成功,第一次 AJAX 调用) - AJAX ->
<form id="same">(成功,第一个 AJAX 响应) -
<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 回复的方式:
- 让 AJAX 只响应和更改特定的小元素
- 将
form重新定位到 AJAX 更改的内容之外
但这两个似乎都很复杂。
必须有某种方式告诉 AJAX 在 form-submit 按钮上的 preventDefault() 该按钮已被 AJAX 更新。我只是不知道那是什么。
或者,还有其他仍然涉及 Vanilla JS 的解决方案吗?
【问题讨论】:
-
您将事件监听器绑定到
ajaxForm表单。然后你替换它(=删除并添加新的),事件监听器也消失了。尝试仅替换表单内容或将事件监听器绑定到容器 div。 -
您可以签入开发工具。用ajax调用替换后看看是否有附加到表单的事件。
-
当您将其附加到
div时,它会中断,因为您提交的是 div,而不是表单。事件冒泡,所以它确实到达了 te div,你只需要应用一些逻辑来提交表单而不是容器 div。 -
“将它绑定到容器 div 会中断 [...]” - 那么您究竟做了什么更改?如果你现在只是把
const form = document.getElementById( "ajaxForm" )变成了const form = document.getElementById( "ajax_changes" ),那么你当然需要相应地修改这部分,const FD = new FormData( form ); -
您的问题的答案是:不,没有。一旦你从 DOM 中移除了表单,eventListener 就会被移除。
标签: javascript php ajax forms preventdefault