表单提交问题后 Ajax 重新加载 DIV

时间:2021-01-28 22:47:58

标签: javascript php html jquery ajax

好的,所以我有一个脚本可以在整个过程中对数据进行分层(在线测试,最多保留 50 个问题的数据)。我最近发现我的 Ajax 和 jquery 代码并没有阻止所有用户获取旨在重新加载的辅助页面,以代替当前页面上的 DIV。所有信息都通过 jquery 和 ajax 传递并且效果很好,但有时在用户第一次访问和第一个问题时,它加载的页面只是为了替换当前的 DIV 信息而不是可见的。

这是我的 Ajax 和 jquery 代码:

<script>
    $("#quizForm").submit(function(event){
        event.preventDefault(); //prevent default action 
        var post_url = $(this).attr("action"); //get form action url
        var form_data = $(this).serialize(); //Encode form elements for submission
        $.post( post_url, form_data, function( response ) {
        $("#prntqst").html( response );
        dataLayer.push({"event" : "formSubmitted", "formName" : "'.$this->quizID.'"});
        });
    });
</script>

这是 HTML:

<div id="prntqst"> <!-- this is DIV set to be reloaded -->
<font class="prntqst-text">Question Goes Here</font>
<form id="quizForm" action="ajax.php" method="post"> <!-- Script setup to handle submitted data -->
<input type="hidden" id="next_question" name="next_question" value="2">
<input type="hidden" id="quiz_type" name="quiz_type" value="learning">
<input type="hidden" id="quiz_name" name="quiz_name" value="knowledge-1">
<label class="container" for="a">Ans A
<input type="radio" name="answers[1]" id="a" value="a">
<span class="checkmark"></span>
</label>
<label class="container" for="b">Ans B
<input type="radio" name="answers[1]" id="b" value="b">
<span class="checkmark"></span>
</label>
<label class="container" for="c">Ans C
<input type="radio" name="answers[1]" id="c" value="c">
<span class="checkmark"></span>
</label>
<div class="subbtn_contain">
<div class="submitbtn">
<input id="submit" type="submit" class="button" value="Next Question">
</div>
</div></div>
</form>
<!-- currently this is the location of Ajax and jquery script -->
<div>

所以当表单提交时,它通过ajax.php页面处理数据,然后页面将下一个问题重新加载到“prntqst”DIV中,在第一个页面加载后每个请求都发送到ajax.php位置,并且所有随后的重新加载都会携带测试正常工作所需的所有数据。但是我发现如果我使用新计算机或清除缓存,第一个请求有时会导致用户被推送到 ajax.php 的位置,而不是他们通过 DIV 重新加载停留在当前 URL。

我已经通过我的分析帐户验证了这个问题,99% 的时间用户仍然显示在正确的 URL 上,就好像 ajax 正确地重新加载了 DIV,但有时它会直接在 ajax.php 脚本中显示用户.

任何想法或意见将不胜感激,

再次感谢!

1 个答案:

答案 0 :(得分:1)

好的,我知道了。

如果您可以在代码块中包含“一些垃圾”,并且如您所说

<块引用>

无论是否使用该行...

那是因为那个代码块根本没有运行。

processData: false 是对对象属性的赋值。在您提供的代码中,它不包含任何对象。然后看起来你试图像这样评论它:<!-- removed from code processData: false; -->,这也应该抛出一个错误。这就是注释行的 HTML 方式。在 JS 中,它会是 // removed from code processData: false;

所以...看起来表单还是提交了。这只是可以“正常”表单提交整个页面重新加载的地方。 作为测试。请尝试完全删除该脚本的页面。你应该看不出有什么区别。


这里还需要解释一下。您正在使用“动态”元素。那些是在页面加载时不存在并在...之后添加的元素,或者在那里被删除/替换的元素。

您必须编写脚本来处理这种情况。

$("#quizForm").submit(function(event){ 中,事件处理程序附加到元素 #quizForm。如果页面第一次加载时页面中没有这样的元素......或者有解析错误......该函数将无法运行。所以 event.preventDefault() 也不会被调用。

然后,假设您修复了该代码块中的所有错误并运行。它直接替换了 #prntqst 中的所有 HTML。因此,对于第二次提交,附加事件处理程序的元素不再存在,该函数将不会再次运行。


解决方案是使用 event delegation 将事件处理程序附加到 document 并将其“委托”给 #quizForm(如果存在,当处理程序被调用)。

那就是$(document).on("event", "delegated_element_selector", function(){

因此,当“事件”在“文档”中触发时,会进行查找以找到“delegated_element_selector”,如果找到,则执行处理程序。

这种方式是为页面中的动态元素设置一些事件处理程序的方式。

此外,关于您将代码放在哪里的问题,我添加了一个 $(document).ready() 处理程序,以确保在对某些元素进行任何 jQuery 查找之前完成初始页面加载。因此,您可以将该脚本放置在您想要的位置。

$(document).ready(function () {
  $(document).on("submit", "#quizForm", function (event) {

    console.log("Custom submit")

    event.preventDefault(); //prevent default action
    var post_url = $(this).attr("action"); //get form action url
    var form_data = $(this).serialize(); //Encode form elements for submission
    $.post(post_url, form_data, function (response) {

      console.log(response)
      $("#prntqst").html(response);
      dataLayer.push({ event: "formSubmitted", formName: "'.$this->quizID.'" });
    });
  });
});

现在您应该在每次提交表单的控制台中看到“自定义提交”。您也应该看到响应是什么。

关于 post_url ,我没有任何 action 属性给 <form>...也许你只是没有在 SO 上发布它。确保有一个。还要确保 response $.post() 应仅接收必要的 HTML,而不是整个页面(包括 <head><body> 等...)。