【发布时间】:2009-02-12 20:39:11
【问题描述】:
我在更新面板中有一个列表框。当我向下滚动并选择一个项目时,它会滚动回列表框的顶部。我听说 dom 不会跟踪回发时的滚动位置。有没有人有关于如何解决这个问题的解决方案/示例?
谢谢, 赛软
【问题讨论】:
我在更新面板中有一个列表框。当我向下滚动并选择一个项目时,它会滚动回列表框的顶部。我听说 dom 不会跟踪回发时的滚动位置。有没有人有关于如何解决这个问题的解决方案/示例?
谢谢, 赛软
【问题讨论】:
您遇到了这个问题,因为当异步请求返回时,UpdatePanel 将滚动的 <select> 元素完全替换为新元素。
可能的解决方案:
在提交UpdatePanel之前(通过调用ClientScriptManager.RegisterOnSubmitStatement方法),使用JavaScript将<select>元素的scrollTop属性存储在隐藏的表单元素中(通过调用ClientScriptManager.RegisterOnSubmitStatement方法),然后将其设置在新的@ 987654333@ 当 AJAX 调用返回时。这会很乏味、容易出错,而且可能不太兼容(请参阅here)。
使用 JavaScript 存储 <select> 的 selectedIndex 属性,并在 AJAX 调用返回时重新选择该项目。如果用户还没有选择任何东西,这显然是行不通的。
【讨论】:
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*****
//在没有更新面板的情况下保持面板/Div的滚动位置
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
【讨论】:
yPos = $('#<%=MyListBox.ClientID %>').scrollTop(); 提取beginRequestHandler 中的数据,$('#<%=MyListBox.ClientID %>').scrollTop(yPos); 将其放回endRequestHandler。
似乎下面的代码示例以如下方式滚动:
Internet Explorer 8:回发后,所选项目是第一个可见项目。
Firefox:回发后,所选项目始终可见(但可能是最后一个可见项目)。
Chrome:如您所说,回发后,由于列表框滚动到顶部,所选项目可能会被隐藏。
【讨论】:
您仍然可以使用包含ListBox 的UpdatePanel 实现部分回发,但通过在UpdatePanel 上设置以下内容来防止它被新实例覆盖:
ChildrenAsTriggers="False"
这如MSDN中所述:
获取或设置一个值,该值指示是否立即回发 UpdatePanel 控件的子控件更新面板的内容。 如果您不想,请将 ChildrenAsTriggers 属性设置为 false 从 UpdatePanel 控件的直接子控件回发到 导致面板内容的更新。
对此的一个警告是,如果您尝试从服务器端对 ListBox 进行任何其他可视化操作(即在回发的项目中添加 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)。
【讨论】: