好的,所以我有一个脚本可以在整个过程中对数据进行分层(在线测试,最多保留 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 脚本中显示用户.
任何想法或意见将不胜感激,
再次感谢!
答案 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>
等...)。