在页面加载之间保留变量
Persist variables between page loads
我正在尝试捕获表单的提交按钮按下,如果表单已提交,页面会刷新并显示一些隐藏字段。我想捕获表单之前是否已提交,如果它在重新加载时提交,我想取消隐藏隐藏字段。我试图使用全局变量来实现这一点,但是我无法使其正常工作。
这是我尝试过的:
var clicked = false;
$(document).ready(function() {
$("input[type='submit'][value='Search']").attr("onclick", "form.act.value='detailSearch'; clicked = true; return true;");
if (clicked == true) {
// show hidden fields
} else {
// don't show hidden fields
}
});
关于这段代码有什么问题有什么建议吗?
你可以试试这个:
$("input[type='submit'][value='Search']").click(function(){
form.act.value='detailSearch';
clicked = true;
return true;
});
由于 HTTP 是无状态的,每次加载页面时,它都会使用您在 JavaScript 中设置的初始值。您不能在 JS 中设置一个全局变量,并在再次加载页面后简单地让该值保留。
有几种方法可以将值存储在另一个地方,以便您可以使用 JavaScript
在加载时对其进行初始化
查询字符串
使用 GET
方法提交表单时,url 会更新为查询字符串 (?parameter=value&something=42
)。您可以通过将表单中的输入字段设置为特定值来利用它。这将是最简单的示例:
<form method="GET">
<input type="hidden" name="clicked" value="true" />
<input type="submit" />
</form>
初始加载页面时,未设置任何查询字符串。当您提交此表单时,输入的 name
和 value
组合将作为 clicked=true
在查询字符串中传递。因此,当页面再次加载该查询字符串时,您可以检查按钮是否被单击。
要读取此数据,您可以在页面加载时使用以下脚本:
function getParameterByName(name) {
name = name.replace(/[\[]/, "\[").replace(/[\]]/, "\]");
var regex = new RegExp("[\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
var clicked = getParameterByName('clicked');
(Source)
能否使用它取决于您的表单当前的工作方式,如果您已经使用 POST 那么这可能会有问题。
此外,对于较大的数据集,这不是最佳选择。传递字符串不是什么大问题,但对于数组和数据对象,您可能应该使用 Web Storage 或 cookie。虽然不同浏览器的细节略有不同,但 URI 长度的实际限制约为 2000 characters
网络存储
随着 HTML5 的引入,我们还获得了 Web 存储,它允许您跨页面加载将信息保存在浏览器中。有 localStorage
可以保存更长时间的数据(只要用户不手动清除它)和 sessionStorage
只在您当前的浏览会话期间保存数据。后者在这里对您很有用,因为您不想在用户稍后回来时将 "clicked" 设置为 true。
这里我设置了按钮点击事件的存储,但你也可以将它绑定到表单提交或其他任何东西。
$('input[type="submit"][value="Search"]').click(function() {
sessionStorage.setItem('clicked', 'true');
});
然后当您加载页面时,您可以使用以下方法检查它是否已设置:
var clicked = sessionStorage.getItem('clicked');
尽管此值仅在本次浏览会话期间保存,但您可能希望提前重置它。为此,请使用:
sessionStorage.removeItem('clicked');
如果您想保存一个 JS 对象或数组,您应该将其转换为字符串。根据规范,应该可以保存其他数据类型,但这还没有在浏览器中正确实现。
//set
localStorage.setItem('myObject', JSON.stringify(myObject));
//get
var myObject = JSON.parse(localStorage.getItem('myObject'));
浏览器支持 pretty great,因此您可以安全地使用它,除非您确实需要支持 old/obscure 浏览器。网络存储是未来。
Cookies
Web 存储的替代方法是将数据保存在 cookie 中。 Cookie 主要用于读取服务器端数据,但也可用于纯客户端数据。
您已经在使用 jQuery,这使得设置 cookie 变得非常容易。同样,我在这里使用 click
事件,但可以在任何地方使用。
$('input[type="submit"][value="Search"]').click(function() {
$.cookie('clicked', 'true', {expires: 1}); // expires in 1 day
});
然后在页面加载时,您可以像这样读取 cookie:
var clicked = $.cookie('clicked');
由于 cookie 在您的情况下跨会话持续存在,因此您需要在完成任何需要使用它的操作后立即取消设置。您不希望用户在一天后回来并且仍然将 clicked
设置为 true。
if(clicked === "true") {
//doYourStuff();
$.cookie('clicked', null);
}
(可以找到 set/read cookie 的非 jQuery 方式 right here)
我个人不会将 cookie 用于像记住单击状态这样简单的事情,但如果查询字符串不是一个选项并且您需要支持不支持 sessionStorage 的真正旧浏览器,这将起作用。您应该首先检查 sessionStorage 来实现它,只有在检查失败时才使用 cookie 方法。
window.name
虽然这对我来说似乎是一种黑客攻击,可能起源于 localStorage/sessionStorage 之前,但您可以将信息存储在 window.name
属性:
window.name = "my value"
它只能存储字符串,所以如果你想保存一个对象,你必须像上面的那样将它字符串化localStorage
例子:
window.name = JSON.stringify({ clicked: true });
主要区别在于此信息不仅在页面刷新时保留,而且在不同的域中保留。但是,它仅限于您所在的当前选项卡。
这意味着您可以在您的页面上保存一些信息,只要用户停留在该选项卡中,即使他浏览到另一个网站并返回,您也可以访问相同的信息。一般来说,我建议不要使用它,除非您需要在单个浏览会话期间实际存储跨域信息。
使用 localeStorage
或 sessionStorage
似乎是最好的选择。
不是将 clicked
变量保存在全局作用域中,而是以这种方式存储它:
if(localeStorage.getItem("clicked") === null)
localeStorage.setItem("clicked", "FALSE"); // for the first time
$(document).ready(function() {
$("input[type='submit'][value='Search']").attr("onclick", "form.act.value='detailSearch';return true;");
var clicked = localeStorage.getItem("clicked") == "FALSE" ? "TRUE" : "FALSE";
localeStorage.setItem("clicked", clicked);
if (clicked == "TRUE") {
// show hidden fields
} else {
// don't show hidden fields
}
});
尝试利用 $.holdReady()
, history
function show() {
return $("form input[type=hidden]")
.replaceWith(function(i, el) {
return "<input type=text>"
});
}
$.holdReady(true);
if (history.state !== null && history.state.clicked === true) {
// show hidden fields
// if `history.state.clicked === true` ,
// replace `input type=hidden` with `input type=text`
show();
console.log(history);
} else {
// don't show hidden fields
console.log(history);
}
$.holdReady(false);
$(document).ready(function() {
$("input[type=submit][value=Search]")
.on("click", function(e) {
e.preventDefault();
if (history.state === null) {
// do stuff
history.pushState({"clicked":true});
// replace `input type=hidden` with `input type=text`
show();
console.log(history);
} else {
// do other stuff
};
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="POST">
<input type="text" name="name" value="" />
<input type="submit" value="Search" />
<input type="hidden" />
<input type="hidden" />
</form>
我正在尝试捕获表单的提交按钮按下,如果表单已提交,页面会刷新并显示一些隐藏字段。我想捕获表单之前是否已提交,如果它在重新加载时提交,我想取消隐藏隐藏字段。我试图使用全局变量来实现这一点,但是我无法使其正常工作。
这是我尝试过的:
var clicked = false;
$(document).ready(function() {
$("input[type='submit'][value='Search']").attr("onclick", "form.act.value='detailSearch'; clicked = true; return true;");
if (clicked == true) {
// show hidden fields
} else {
// don't show hidden fields
}
});
关于这段代码有什么问题有什么建议吗?
你可以试试这个:
$("input[type='submit'][value='Search']").click(function(){
form.act.value='detailSearch';
clicked = true;
return true;
});
由于 HTTP 是无状态的,每次加载页面时,它都会使用您在 JavaScript 中设置的初始值。您不能在 JS 中设置一个全局变量,并在再次加载页面后简单地让该值保留。
有几种方法可以将值存储在另一个地方,以便您可以使用 JavaScript
在加载时对其进行初始化查询字符串
使用 GET
方法提交表单时,url 会更新为查询字符串 (?parameter=value&something=42
)。您可以通过将表单中的输入字段设置为特定值来利用它。这将是最简单的示例:
<form method="GET">
<input type="hidden" name="clicked" value="true" />
<input type="submit" />
</form>
初始加载页面时,未设置任何查询字符串。当您提交此表单时,输入的 name
和 value
组合将作为 clicked=true
在查询字符串中传递。因此,当页面再次加载该查询字符串时,您可以检查按钮是否被单击。
要读取此数据,您可以在页面加载时使用以下脚本:
function getParameterByName(name) {
name = name.replace(/[\[]/, "\[").replace(/[\]]/, "\]");
var regex = new RegExp("[\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
var clicked = getParameterByName('clicked');
(Source)
能否使用它取决于您的表单当前的工作方式,如果您已经使用 POST 那么这可能会有问题。
此外,对于较大的数据集,这不是最佳选择。传递字符串不是什么大问题,但对于数组和数据对象,您可能应该使用 Web Storage 或 cookie。虽然不同浏览器的细节略有不同,但 URI 长度的实际限制约为 2000 characters
网络存储
随着 HTML5 的引入,我们还获得了 Web 存储,它允许您跨页面加载将信息保存在浏览器中。有 localStorage
可以保存更长时间的数据(只要用户不手动清除它)和 sessionStorage
只在您当前的浏览会话期间保存数据。后者在这里对您很有用,因为您不想在用户稍后回来时将 "clicked" 设置为 true。
这里我设置了按钮点击事件的存储,但你也可以将它绑定到表单提交或其他任何东西。
$('input[type="submit"][value="Search"]').click(function() {
sessionStorage.setItem('clicked', 'true');
});
然后当您加载页面时,您可以使用以下方法检查它是否已设置:
var clicked = sessionStorage.getItem('clicked');
尽管此值仅在本次浏览会话期间保存,但您可能希望提前重置它。为此,请使用:
sessionStorage.removeItem('clicked');
如果您想保存一个 JS 对象或数组,您应该将其转换为字符串。根据规范,应该可以保存其他数据类型,但这还没有在浏览器中正确实现。
//set
localStorage.setItem('myObject', JSON.stringify(myObject));
//get
var myObject = JSON.parse(localStorage.getItem('myObject'));
浏览器支持 pretty great,因此您可以安全地使用它,除非您确实需要支持 old/obscure 浏览器。网络存储是未来。
Cookies
Web 存储的替代方法是将数据保存在 cookie 中。 Cookie 主要用于读取服务器端数据,但也可用于纯客户端数据。
您已经在使用 jQuery,这使得设置 cookie 变得非常容易。同样,我在这里使用 click
事件,但可以在任何地方使用。
$('input[type="submit"][value="Search"]').click(function() {
$.cookie('clicked', 'true', {expires: 1}); // expires in 1 day
});
然后在页面加载时,您可以像这样读取 cookie:
var clicked = $.cookie('clicked');
由于 cookie 在您的情况下跨会话持续存在,因此您需要在完成任何需要使用它的操作后立即取消设置。您不希望用户在一天后回来并且仍然将 clicked
设置为 true。
if(clicked === "true") {
//doYourStuff();
$.cookie('clicked', null);
}
(可以找到 set/read cookie 的非 jQuery 方式 right here)
我个人不会将 cookie 用于像记住单击状态这样简单的事情,但如果查询字符串不是一个选项并且您需要支持不支持 sessionStorage 的真正旧浏览器,这将起作用。您应该首先检查 sessionStorage 来实现它,只有在检查失败时才使用 cookie 方法。
window.name
虽然这对我来说似乎是一种黑客攻击,可能起源于 localStorage/sessionStorage 之前,但您可以将信息存储在 window.name
属性:
window.name = "my value"
它只能存储字符串,所以如果你想保存一个对象,你必须像上面的那样将它字符串化localStorage
例子:
window.name = JSON.stringify({ clicked: true });
主要区别在于此信息不仅在页面刷新时保留,而且在不同的域中保留。但是,它仅限于您所在的当前选项卡。
这意味着您可以在您的页面上保存一些信息,只要用户停留在该选项卡中,即使他浏览到另一个网站并返回,您也可以访问相同的信息。一般来说,我建议不要使用它,除非您需要在单个浏览会话期间实际存储跨域信息。
使用 localeStorage
或 sessionStorage
似乎是最好的选择。
不是将 clicked
变量保存在全局作用域中,而是以这种方式存储它:
if(localeStorage.getItem("clicked") === null)
localeStorage.setItem("clicked", "FALSE"); // for the first time
$(document).ready(function() {
$("input[type='submit'][value='Search']").attr("onclick", "form.act.value='detailSearch';return true;");
var clicked = localeStorage.getItem("clicked") == "FALSE" ? "TRUE" : "FALSE";
localeStorage.setItem("clicked", clicked);
if (clicked == "TRUE") {
// show hidden fields
} else {
// don't show hidden fields
}
});
尝试利用 $.holdReady()
, history
function show() {
return $("form input[type=hidden]")
.replaceWith(function(i, el) {
return "<input type=text>"
});
}
$.holdReady(true);
if (history.state !== null && history.state.clicked === true) {
// show hidden fields
// if `history.state.clicked === true` ,
// replace `input type=hidden` with `input type=text`
show();
console.log(history);
} else {
// don't show hidden fields
console.log(history);
}
$.holdReady(false);
$(document).ready(function() {
$("input[type=submit][value=Search]")
.on("click", function(e) {
e.preventDefault();
if (history.state === null) {
// do stuff
history.pushState({"clicked":true});
// replace `input type=hidden` with `input type=text`
show();
console.log(history);
} else {
// do other stuff
};
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="POST">
<input type="text" name="name" value="" />
<input type="submit" value="Search" />
<input type="hidden" />
<input type="hidden" />
</form>