【问题标题】:Ajax reload DIV after form submit issue表单提交问题后Ajax重新加载DIV
【发布时间】:2021-01-28 22:47:58
【问题描述】:

好的,所以我有一个脚本,可以在整个过程中分层数据(在线测试,数据最多保留 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 的位置,而不是他们停留在当前 URL 并重新加载 DIV。

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

任何想法或 cmets 将不胜感激,

再次感谢!

【问题讨论】:

  • 由于processData: false;,您应该在控制台中至少有一个错误。类似于processData is undefined 之类的解析错误,例如unexpected ":"...——我很惊讶它在 99% 的时间里都能正常工作。
  • 我使用或不使用该行,所以我将删除它。在玩了一些之后,如果页面接近或一直加载,问题就不会发生。如果当页面第一次加载提交按钮时,它会加载凉亭栏中的 ajax.php 脚本。所以这似乎更像是一个加载问题。
  • 我尝试将代码添加到页面的标题中,但完成后它根本不起作用。难道是代码只需要在代码中进一步移动吗?可能在提交按钮之前?
  • 推送到“ajax.php”的位置意味着用户被重定向到特定的 PHP 页面,对吧?
  • 还有一件事,你提供的Html,它准确吗?因为关闭表单标记似乎超出了“prntqst”div。当您在“prntqst”div 中覆盖 HTML 时,这可能会给您带来问题。

标签: javascript php html jquery ajax


【解决方案1】:

好的,我明白了。

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

不管有没有这条线都可以工作......

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

processData: false 是对对象属性的赋值。在您提供的代码中,它位于任何对象之外。然后看起来你试图像这样评论它:&lt;!-- removed from code processData: false; --&gt;,这也应该引发错误。这是注释行的 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 ,我对&lt;form&gt; 没有任何action 属性...也许您只是没有在SO 上发布它。确保有一个。还要确保 response $.post() 应该只接收必要的 HTML 而不是整个页面(&lt;head&gt;&lt;body&gt; 等...)。

【讨论】:

猜你喜欢
  • 2020-06-27
  • 2012-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-05
  • 1970-01-01
相关资源
最近更新 更多