我有一个包含两个div的ASP.NET页面。两者都有搜索字段和每个搜索按钮。当我第一次来到这个页面时,Div A有“SearchDiv”类,而Div B有“SearchDivDisabled”。这些类会更改外观,以便用户知道他们当前启用的搜索类型。
单击Div B时,JavaScript会将其类更改为“SearchDiv”,并将Div A更改为“SearchDivDisabled”。这一切都像一个魅力。我遇到的问题是当用户更改为Div B时,单击Div B的搜索按钮(显然会重定向到结果页面),然后使用浏览器的后退按钮。当他们返回搜索页面时,Div A再次启用,Div B被禁用,即使他们上次使用Div B.在搜索按钮事件处理程序中,我在重定向之前设置了Div的class属性,希望这会更新服务器上的页面,所以当用户返回时,它们最后启用的Div仍将被启用(无论在第一次访问该页面时启用了哪一个)。
我认为这涉及到ViewState,但我不确定为什么没有保存class属性,因此当用户返回页面时它将被恢复。有没有我在这里缺少的东西,或者一些简单的方法来保证我想要的行为?谢谢!
编辑:这是按钮事件处理程序代码:
protected void RedirectToResults(int searchEnum, string resultPage)
{
ShowContainer(searchEnum);
Response.Redirect(resultPage + this.webParams.getAllVariablesString(null));
}
protected void ShowContainer(int searchContainerToShow)
{
if (searchContainerToShow < 0 || searchContainerToShow > SearchContainers.Count || SearchContainers.Count == 0)
return;
//disable all search panels
foreach (SearchContainer container in SearchContainers.Values)
{
container.searchDiv.Attributes.Add("class", "SearchDivDisabled");
}
//enable selected panel
SearchContainers[searchContainerToShow].searchDiv.Attributes.Add("class", "SearchDiv");
}
从实际按钮事件处理程序调用 RedirectToResults()
,其中枚举表示所选搜索面板和结果页面URL。 SearchContainers是一个将整数映射到搜索Div的字典。重要的代码是最后一行,我用“主动”搜索类更新选定的搜索容器,而不是禁用的(我分配给其他div)
其他更新:过去几天我一直在与这个问题作斗争。我有点能够使用以下代码(在page_load中):
Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
Response.AppendHeader("Expires", "0"); // Proxies.
但这确实不是一个解决方案,因为其他所有正确缓存的内容都会丢失,这让我比开始时更糟糕。其他一切似乎都很好,只是div的阶级导致我挣扎。
修改:想要为遇到此问题的其他人更新此信息。虽然我相信这里有一个解决方案,设置页面的可缓存性以强制浏览器回发,但我无法让它在所有浏览器上100%运行(主要是Firefox给我配合,这是一个记录的错误)。我相信cookie解决方案可行,但我觉得这可能比仅仅试图存储几个div的状态要复杂一些。
我最终做的是将div的类绑定到它的相关单选按钮的状态(div旁边有单选按钮,允许用户以更直观的方式启用搜索面板)。我注意到这些单选按钮在使用后退按钮时保留了正确的选中值,因此我可以保证它们会指示要启用的正确div。所以在JavaScript的onload中我检查启用了哪个单选按钮,然后相应地调整搜索div的类。这是一个相当大的黑客,但在所有浏览器中100%工作,只需要大约10行JavaScript。
答案 0 :(得分:4)
因为您没有回发来更改div的样式,所以当用户点击后退按钮时,它会将其恢复到最初发布页面的方式。解决此问题的简单方法是让按钮导致切换样式的回发。
答案 1 :(得分:3)
将设置存储在客户端的cookie中,然后在加载页面时通过JavaScript检查cookie并更改CSS类。解决此问题的其他方法可能不起作用,因为当用户点击Back
按钮时,并不总是从服务器请求页面。
使用jQuery cookie plugin
// this function will update the style of the divs based on the cookie's settings
function updateClass(){
var val = $.cookie('myCookieName');
// set your div's class
if (!val || val=='divA')
{
$('#divA').removeClass('SearchDivDisabled');
$('#divA').addClass('SearchDiv');
$('#divB').removeClass('SearchDiv');
$('#divB').addClass('SearchDivDisabled');
}else{
$('#divB').removeClass('SearchDivDisabled');
$('#divB').addClass('SearchDiv');
$('#divA').removeClass('SearchDiv');
$('#divA').addClass('SearchDivDisabled');
}
}
// call this passing in 'divA' or 'divB' depending on which is selected
function updatePage(selectedDiv){
$.cookie('myCookieName', selectedDiv, { path: '/', expires: 10 });
updateClass();
}
// change the class of the divs when the page is finished rendering
$(document).ready(function(){updateClass();}):
答案 2 :(得分:1)
我认为ViewState不是问题所在;它可能需要在客户端javascript代码中管理,因为客户端上的切换状态不会自动反映在服务器上...
您希望通过历史记录点功能管理浏览器历史记录:http://msdn.microsoft.com/en-us/library/cc488548.aspx
HTH。
答案 3 :(得分:1)
正如我之前的回答中所提到的,您可以使用会话变量实现所需的一切。 既然你已经提到过持久的DIV选择,那么我曾要求你在会话变量中使用它。 如果您希望保留其他表单数据,并将它们全部转储到会话变量中(确保在完成后将它们清理干净)
这是满足您要求的最简单方法。
您还在使用
Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
Response.AppendHeader("Expires", "0"); // Proxies.
你可以简单地使用
Response.Cache.SetCacheability(HttpCacheability.Private);
在你的Page_load中并实现相同的功能
如果您对此有任何特殊关注,请与我们联系。
答案 4 :(得分:1)
这可以通过两种方式解决。
如果每个搜索表单都发布到不同的URL,则每个URL都应设置一个会话变量,例如“LastSearchMethd”,设置为“A”或“B”。 如果它们都发布到相同的URL,则只需为每个表单分别包含一个包含“A”或“B”的隐藏字段,并将提交的值保存在会话变量中。
无论哪种方式,您都需要渲染每个DIV的样式,具体取决于会话变量的值。
正如其他海报所提到的,将缓存设置正确也是一个考虑因素。
答案 5 :(得分:0)
在搜索按钮中执行重定向之前,您可以在SESSION变量中存储当前设置为“SearchDiv”类的div的id,在搜索页面的上载期间获取div并在其上设置适当的类。
这样你就可以继续使用你的javascript在div上切换类,只保存数据,然后重定向到不同的页面,避免不必要的帖子
答案 6 :(得分:0)
使用Chrome中的“后退”按钮返回页面时,对DOM的大多数更改不会保留。 (我相信这在其他浏览器中可能会有所不同,因为它们实现了BFcache(后退缓存),目前正在为Chrome开发)。
仍然是输入值,例如单选按钮和隐藏的输入。
因此,如果将更改存储在(隐藏的)输入中,则可以在pageshow event上还原DOM。 (如果您检查Mozilla页面,对事件的支持似乎就这样,但是CanIUse.com更为乐观:https://www.caniuse.com/#search=pageshow)