我在更新面板中有一个列表框。当我向下滚动并选择一个项目时,它会滚动回到列表框的顶部。我听说dom没有跟踪回滚时的滚动位置。有没有人有解决方案/例如如何解决这个问题?保持更新面板中列表框的滚动位置,而不是页面
感谢, XaiSoft
我在更新面板中有一个列表框。当我向下滚动并选择一个项目时,它会滚动回到列表框的顶部。我听说dom没有跟踪回滚时的滚动位置。有没有人有解决方案/例如如何解决这个问题?保持更新面板中列表框的滚动位置,而不是页面
感谢, XaiSoft
您正在运行到这个问题,因为当异步请求回来的UpdatePanel
完全替换一个新的滚动<select>
元素。
可能的解决方案:
使用JavaScript的<select>
元素的scrollTop
财产保存在一个隐藏的表单元素的UpdatePanel
提交前(通过调用ClientScriptManager.RegisterOnSubmitStatement
方法),然后将它设置在当AJAX调用返回时,新的<select>
。这将是乏味的,容易出错的,并且可能不是很兼容(参见here)。
使用JavaScript来存储<select>
的selectedIndex
属性,并在AJAX调用返回时重新选择该项。如果用户还没有选择任何东西,这显然不起作用。
看来,在下列方式下面的代码示例滚动:
的Internet Explorer 8:回传后所选择的项目是第一个可见项目。
火狐:回传后所选择的项目始终是可见的(但可能是最后一个可见项)。
铬:回发后,所选择的项目可能会因为列表框滚动到顶部被隐藏,就像你说的。
<asp:UpdatePanel ID="up1" runat="server"> <ContentTemplate> <asp:ListBox ID="lb1" runat="server" Height="100px" AutoPostBack="true"> <asp:ListItem>A</asp:ListItem> <asp:ListItem>B</asp:ListItem> <asp:ListItem>C</asp:ListItem> <asp:ListItem>D</asp:ListItem> <asp:ListItem>E</asp:ListItem> <asp:ListItem>F</asp:ListItem> <asp:ListItem>G</asp:ListItem> <asp:ListItem>H</asp:ListItem> </asp:ListBox> </ContentTemplate> </asp:UpdatePanel>
对于选定的项目,Firefox会滚动至顶端不可预知的位置。起初,我认为这可能是因为列表框中的项目数量太多,但是当选择一个特定的项目时......有时它会在回发后保持可见状态,有时Firefox会滚动到顶端。这个列表没有被重建,同样的事情发生时,任何项目被点击,所以这显然是一个Firefox的错误,它仍然存在3.0.13版本。 – Triynko 2009-08-07 14:57:46
var xPos, yPos;
var prm = Sys.WebForms.PageRequestManager.getInstance();
function BeginRequestHandler(sender, args) {
if (($get('Panel1')) != null) {
xPos = $get('Panel1').scrollLeft;
yPos = $get('Panel1').scrollTop;
}
}
function EndRequestHandler(sender, args) {
if (($get('Panel1')) != null) {
$get('Panel1').scrollLeft = xPos;
$get('Panel1').scrollTop = yPos;
}
}
prm.add_beginRequest(BeginRequestHandler);
prm.add_endRequest(EndRequestHandler);
//Note: "Panel1" Panel or div u want to maintain scroll position
//Note: This Java Script should be added after Scriptmanager*****
//保持滚动位置的面板/格与出更新面板
window.onload = function() {
var strCook = document.cookie;
if (strCook.indexOf("!~") != 0) {
var intS = strCook.indexOf("!~");
var intE = strCook.indexOf("~!");
var strPos = strCook.substring(intS + 2, intE);
document.getElementById('Panel1').scrollTop = strPos;
}
}
function SetDivPosition() {
var intY = document.getElementById('Panel1').scrollTop;
document.title = intY;
document.cookie = "yPos=!~" + intY + "~!";
}
//Note: "Panel1" Panel id or div id for which u want to maintain scroll position
您仍然可以实现使用含有ListBox
的UpdatePanel
的局部回传,但防止它被覆盖的一个新的实例通过设置在UpdatePanel
如下:
ChildrenAsTriggers="False"
这在MSDN的规定:
获取或设置一个值,该值指示从UpdatePanel控件的即时 子控件的回发是否更新面板的内容。 如果您不希望将UpdatePanel控件的直接子控件的 回发更新为 ,则将ChildrenAsTriggers属性设置为false会导致更新面板内容。
一个需要注意的情况是,如果你正在尝试做任何其他的可视化操控,从服务器端(即添加CSS
属性上回发的项目)列表框,那么你就不会看到他们渲染,直到另一个不相关的回发发生。如果你正在做的是选择比设置ChildrenAsTriggers="False"
将工作。
对于我正在开发的企业应用程序,事实证明,MasterPage.Master页面正在处理Sys.WebForms.PageRequestManager.getInstance()。add_endRequest事件并在其中设置window.scroll(0,0)。内容页显然正在执行内容页的UpdatePanel的每个触发器上的window.scroll(0,0)。我尝试覆盖内容页面中的add_endRequest功能,但无法使其工作。最终,我只是修改Master.Master,不做window.scroll(0,0)。
我发现这个解决方案,它实际上工作。 http://basgun.wordpress.com/2008/06/09/maintain-scroll-position-updatepanel-postback/ – Xaisoft 2009-02-12 21:03:51
好。这听起来像IE6上的selectTop存在问题。本页面的第一条评论解释了如何解决该问题:http://geekswithblogs.net/lorint/archive/2005/12/16/63289.aspx – 2009-02-12 21:10:49