我在用户会话过期后提交表单时实现了“登录以继续”功能,但我遇到了一些我不太了解的事情。
当我将提交监听器添加到表单时,它在提交之前需要3次提交尝试(登录时):第1次,没有任何内容打印到控制台;第二个提交打印'预防表单提交',第三个提交最终允许提交继续。之后,每2个提交将起作用,第一个显示上面的控制台行。
但是,如果我将'this'传递给onreadystatechange函数,它的工作方式与我期望的每次一样 - 唯一的问题是我在JS控制台中遇到'SyntaxError:missing formal parameter'错误,显然因为我提供的是一个值来代替参数名称。
所以我的问题是:如何正确地执行此操作,如果我不向函数提供'this'(事件监听器所附加的当前表单元素),为什么它不起作用? ?
我不想在这个特定项目中使用JQuery或任何外部库,所以请不要在你的答案中使用任何。
form.addEventListener('submit', function(e) {
var xmlhttp = new XMLHttpRequest();
// xmlhttp.onreadystatechange = function() { // doesn't work the way I want
xmlhttp.onreadystatechange = function(this) { // works the way I want
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
if (xmlhttp.responseText === 'true') {
form.setAttribute('allow_submit', 'true');
form.submit();
} else {
form.setAttribute('allow_submit', 'false');
}
}
}
xmlhttp.open("POST", "xml_request_router.php", true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send('route_id=active_session_check');
console.log("Preventing form submission");
if (form.getAttribute('allow_submit') !== 'true') {
e.preventDefault();
}
});
我尝试过使用回调并将参数传递给它,但行为与上面完全相同。这是我的尝试:
function stateChanged(xmlhttp, form) {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
if (xmlhttp.responseText === 'true') {
form.setAttribute('allow_submit', 'true');
form.submit();
} else {
form.setAttribute('allow_submit', 'false');
}
}
}
// and here's how I called it from the event listener:
xmlhttp.onreadystatechange = function() { // adding 'this' results in correct behavior
stateChanged(xmlhttp, form);
}
编辑:以下是我检索表单元素的方法:
var forms = document.getElementsByTagName('form');
for (i = 0; i < forms.length; i++) {
var form = forms[i];
// rest of code follows from here
编辑:为了防止其他人来到这里寻找解决方案,我能够让闭包正常工作的唯一方法是将NodeList转换为数组并迭代它:
function nodeListToArray(nl) {
var i = nl.length, arr = new Array(i);
for(; i--; arr[i] = nl[i]);
return arr;
}
var forms = document.getElementsByTagName('form');
nodeListToArray(forms).forEach(function(form) {
form.addEventListener('submit', function(e) {
// this way does NOT work:
// return function(e, this) {
// original logic here
// }
// but this way DOES:
return notSureWhyThisIsNecessary(e, this);
});
});
function notSureWhyThisIsNecessary(e, form) {
// original logic here, i.e. xmlhttp request etc.
}
因此,如果像我自己一样,JavaScript闭包(特别是在上述情况下)对你来说仍然有些神秘,即使在阅读了大量关于它们的文章之后,上面的代码片段也许会有所帮助。欢呼声。