在页面加载之间保持变量

我试图捕捉表单的提交按钮,如果表单被提交,页面将刷新,并显示一些隐藏字段。我想捕捉表单是否已经提交之前或没有,如果它提交了重新加载,我想取消隐藏字段。我试图使用一个全局变量来实现这一点,但我无法使其正常工作。

以下是我试过的方法:

  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
}
});

对于这个代码的错误有什么建议吗?

91424 次浏览

你可以试试这个:

 $("input[type='submit'][value='Search']").click(function(){
form.act.value='detailSearch';
clicked = true;
return true;
});

由于 HTTP 是无状态的,因此每次加载页面时,它都会使用在 JavaScript 中设置的任何初始值。您不能在 JS 中设置一个全局变量,只是在再次加载页面之后保留该值。

有几种方法可以将值存储在另一个地方,这样就可以使用 JavaScript 在加载时初始化它


查询字符串

当使用 GET方法提交表单时,将使用查询字符串(?parameter=value&something=42)更新 URL。可以通过将表单中的输入字段设置为某个值来利用这一点。这是最简单的例子:

<form method="GET">
<input type="hidden" name="clicked" value="true" />
<input type="submit" />
</form>

在页的初始加载时,不设置查询字符串。当您提交此表单时,输入的 namevalue组合将作为 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个字符左右


网络存储

随着 HTML5的引入,我们还得到了 Web Storage,它允许您在浏览器中跨页面加载保存信息。有 localStorage可以保存数据较长的时间(只要用户不手动清除它)和 sessionStorage保存数据只有在您当前的浏览会话。在这里,后者对您很有用,因为您不希望在用户稍后返回时将“单击”设置为 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'));

浏览器支持是 挺好的,所以使用它应该是安全的,除非您需要支持非常老/模糊的浏览器。网络存储是未来的趋势。


饼干

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);
}

(可以找到设置/读取 cookie 的非 jQuery 方式 right here)

我个人不会使用 cookie 来记住一个简单的点击状态,但如果查询字符串不是一个选项,你需要支持真正的老浏览器,不支持 sessionStorage 这将工作。应该首先通过检查 sessionStorage 来实现它,并且只有在检查失败时才使用 cookie 方法。


Window 姓名

虽然在我看来,这似乎是一种黑客行为,可能起源于 localStorage/sessionStorage 之前,但是您可以将信息存储在 window.name属性中:

window.name = "my value"

它只能存储字符串,所以如果你想保存一个对象,你就必须像上面的 localStorage例子一样将其字符串化:

window.name = JSON.stringify({ clicked: true });

主要区别在于,这些信息不仅在页面刷新时保留,而且在不同的域中保留。但是,它仅限于您所在的当前选项卡。

这意味着你可以在你的页面上保存一些信息,只要用户停留在那个标签页,你就可以访问相同的信息,即使他浏览了另一个网站并返回。一般来说,我建议不要使用这种方法,除非您需要在单个浏览会话期间实际存储跨域信息。

Using localeStorage or sessionStorage seems to be the best bet.

不需要将 clicked变量保存在 global 作用域中,而是以这种方式存储它:

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>