Javascript 在页面加载之间保持变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29986657/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Persist variables between page loads
提问by Neophile
I am trying to capture the submit button press of my form and if the form is submitted, the page refreshes and I show a few hidden fields. I would like to capture whether the form has been submitted before or not and if it submitted on reload, I would like to unhide the hidden fields. I was trying to use a global variable to achieve this, however I was unable to make it work properly.
我正在尝试捕获表单的提交按钮按下,如果表单已提交,页面会刷新并显示一些隐藏字段。我想捕获表单之前是否已提交,如果它在重新加载时提交,我想取消隐藏隐藏字段。我试图使用全局变量来实现这一点,但是我无法使其正常工作。
Here is what I tried:
这是我尝试过的:
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
}
});
Any suggestions on what is wrong with this code?
关于此代码有什么问题的任何建议?
回答by Stephan Muller
As HTTP is stateless, every time you load the page it will use the initial values of whatever you set in JavaScript. You can't set a global variable in JS and simply make that value stay after loading the page again.
由于 HTTP 是无状态的,每次加载页面时,它将使用您在 JavaScript 中设置的任何初始值。您不能在 JS 中设置全局变量,并在再次加载页面后简单地保留该值。
There are a couple of ways you could store the value in another place so that you can initialize it on load using JavaScript
有几种方法可以将值存储在另一个位置,以便在加载时使用 JavaScript 对其进行初始化
Query string
请求参数
When submitting a form using the GETmethod, the url gets updated with a query string (?parameter=value&something=42). You can utilize this by setting an input field in the form to a certain value. This would be the simplest example:
使用该GET方法提交表单时,url 将使用查询字符串 ( ?parameter=value&something=42)进行更新。您可以通过将表单中的输入字段设置为特定值来利用此功能。这将是最简单的例子:
<form method="GET">
<input type="hidden" name="clicked" value="true" />
<input type="submit" />
</form>
On initial load of the page, no query string is set. When you submit this form, the nameand valuecombination of the input are passed in the query string as clicked=true. So when the page loads again with that query string you can check if the button was clicked.
在页面的初始加载时,没有设置查询字符串。当您提交此表单时,输入的name和value组合在查询字符串中作为 传递clicked=true。因此,当使用该查询字符串再次加载页面时,您可以检查按钮是否被单击。
To read this data, you can use the following script on page load:
要读取此数据,您可以在页面加载时使用以下脚本:
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)
(来源)
Ability to use this depends on how your form currently works, if you already use a POST then this could be problematic.
使用它的能力取决于您的表单当前的工作方式,如果您已经使用了 POST,那么这可能会出现问题。
In addition, for larger sets of data this is less than optimal. Passing around a string isn't a big deal but for arrays and objects of data you should probably use Web Storage or cookies. While the details differ a bit across browsers, the practical limit to URI length is around 2000 characters
此外,对于较大的数据集,这不是最佳选择。传递字符串没什么大不了的,但对于数组和数据对象,您可能应该使用 Web Storage 或 cookie。虽然详细信息因浏览器而异,但 URI 长度的实际限制约为2000 个字符
Web Storage
网络存储
With the introduction of HTML5 we also got Web Storage, which allows you to save information in the browser across page loads. There is localStoragewhich can save data for a longer period (as long as the user doesn't manually clear it) and sessionStoragewhich saves data only during your current browsing session. The latter is useful for you here, because you don't want to keep "clicked" set to true when the user comes back later.
随着 HTML5 的引入,我们还获得了 Web Storage,它允许您跨页面加载在浏览器中保存信息。有localStorage哪些可以更长时间地保存数据(只要用户不手动清除它),sessionStorage哪些仅在您当前的浏览会话期间保存数据。后者在这里对您很有用,因为您不想在用户稍后回来时将“clicked”设置为 true。
Here I set the storage on the button click event, but you could also bind it to form submit or anything else.
在这里,我在按钮单击事件上设置了存储,但您也可以将其绑定到表单提交或其他任何内容。
$('input[type="submit"][value="Search"]').click(function() {
sessionStorage.setItem('clicked', 'true');
});
Then when you load the page, you can check if it's set using this:
然后当你加载页面时,你可以检查它是否使用这个设置:
var clicked = sessionStorage.getItem('clicked');
Even though this value is only saved during this browsing session, it might be possible you want to reset it earlier. To do so, use:
即使此值仅在此浏览会话期间保存,您也可能希望更早地重置它。为此,请使用:
sessionStorage.removeItem('clicked');
If you would want to save a JS object or array you should convert that to a string. According to the spec it should be possible to save other datatypes, but this isn't correctly implemented across browsers yet.
如果您想保存 JS 对象或数组,您应该将其转换为字符串。根据规范,应该可以保存其他数据类型,但这还没有在浏览器中正确实现。
//set
localStorage.setItem('myObject', JSON.stringify(myObject));
//get
var myObject = JSON.parse(localStorage.getItem('myObject'));
Browser support is pretty greatso you should be safe to use this unless you need to support really old/obscure browsers. Web Storage is the future.
浏览器支持非常好,因此除非您需要支持非常旧/晦涩的浏览器,否则您应该可以安全地使用它。网络存储是未来。
Cookies
饼干
An alternative to Web Storage is saving the data in a cookie. Cookies are mainly made to read data server-side, but can be used for purely client-side data as well.
Web 存储的替代方法是将数据保存在 cookie 中。Cookie 主要用于读取服务器端数据,但也可用于纯客户端数据。
You already use jQuery, which makes setting cookies quite easy. Again, I use the clickevent here but could be used anywhere.
您已经使用了 jQuery,这使得设置 cookie 变得非常容易。同样,我在click这里使用该事件,但可以在任何地方使用。
$('input[type="submit"][value="Search"]').click(function() {
$.cookie('clicked', 'true', {expires: 1}); // expires in 1 day
});
Then on page load you can read the cookie like this:
然后在页面加载时,您可以像这样读取 cookie:
var clicked = $.cookie('clicked');
As cookies persist across sessions in your case you will need to unset them as soon as you've done whatever you need to do with it. You wouldn't want the user to come back a day later and still have clickedset to true.
由于 cookie 在您的情况下跨会话持续存在,您需要在完成任何需要对其进行处理后立即取消设置。您不希望用户在一天后回来并且仍然clicked设置为 true。
if(clicked === "true") {
//doYourStuff();
$.cookie('clicked', null);
}
(a non-jQuery way to set/read cookies can be found right here)
(可以在此处找到设置/读取 cookie 的非 jQuery 方式)
I personally wouldn't use a cookie for something simple as remembering a clicked state, but if the query string isn't an option and you need to support really old browsers that don't support sessionStorage this will work. You should implement that with a check for sessionStorage first, and only if that fails use the cookie method.
我个人不会将 cookie 用于记住点击状态这样简单的事情,但是如果查询字符串不是一个选项,并且您需要支持不支持 sessionStorage 的非常旧的浏览器,这将起作用。您应该首先通过检查 sessionStorage 来实现它,并且只有在失败时才使用 cookie 方法。
window.name
窗口名称
Although this seems like a hack to me that probably originated from before localStorage/sessionStorage, you could store information in the window.nameproperty:
尽管这对我来说似乎是一种黑客攻击,可能起源于 localStorage/sessionStorage 之前,但您可以将信息存储在window.name属性中:
window.name = "my value"
It can only store strings, so if you want to save an object you'll have to stringify it just like the above localStorageexample:
它只能存储字符串,所以如果你想保存一个对象,你必须像上面的localStorage例子一样对其进行字符串化:
window.name = JSON.stringify({ clicked: true });
The major difference is that this information is retained across not only page refreshes but also different domains. However, it is restricted to the current tab you're in.
主要区别在于,此信息不仅保留在页面刷新中,还保留在不同的域中。但是,它仅限于您所在的当前选项卡。
This means you could save some information on your page and as long as the user stays in that tab, you could access that same information even if he browsed to another website and back. In general, I would advice against using this unless you need to actually store cross-domain information during a single browsing session.
这意味着您可以在您的页面上保存一些信息,只要用户停留在该选项卡中,即使他浏览到另一个网站并返回,您也可以访问相同的信息。一般来说,除非您需要在单个浏览会话期间实际存储跨域信息,否则我建议不要使用它。
回答by guest271314
Try utilizing $.holdReady(), history
尝试利用$.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>
回答by me_digvijay
Using localeStorageor sessionStorageseems to be the best bet.
使用localeStorageorsessionStorage似乎是最好的选择。
Intead of saving the clickedvariable in the globle scope store it this way:
Intead 将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
}
});
回答by renakre
You could try this:
你可以试试这个:
$("input[type='submit'][value='Search']").click(function(){
form.act.value='detailSearch';
clicked = true;
return true;
});

