7

异步回发后将滚动位置重置到页面顶部的最佳方法是什么?

异步回发从 ASP.NET GridView CommandField 列启动,并在 GridView OnRowCommand 中调用 ASP.NET 更新面板 Update 方法。

我当前的应用程序是一个 ASP.NET 3.5 网站。

编辑:我收到了大家的优秀反馈,我结束了在脚本标签中使用 PageRequestManager 方法,但我的下一个问题是:

如何将其配置为仅在用户单击 GridView 控件中的 ASP.NET CommandField 时执行?我在页面上有其他按钮执行异步回发,我不想滚动到页面顶部。

编辑 1:我开发了一个不需要使用 PageRequestManager 的解决方案。请参阅我的后续答案以获取解决方案。

4

8 回答 8

17

当您使用 UpdatePanels 时,您需要连接到 ASP.NET AJAX PageRequestManager

您需要向endRequest事件挂钩添加一个方法,这些挂钩是:

在异步回发完成并将控制权返回给浏览器后引发。

所以你会有类似的东西:

<script type="text/javascript">
  Sys.WebForms.PageRequestManager.getInstance().add_endRequest(pageLoaded);

  function pageLoaded(sender, args) {
     window.scrollTo(0,0);
  }
</script>

一旦更新请求完成,这将强制浏览器滚动回页面顶部。

当然,您还可以加入其他事件:

beginRequest // Raised before the request is sent
initializeRequest // Raised as the request is initialised (good for cancelling)
pageLoaded // Raised once the request has returned, and content is loaded
pageLoading // Raised once the request has returned, and before content is loaded

异步回发的美妙之处在于页面将保持滚动高度,而无需您设置 MaintainScrollPosition,因为没有“整页重新加载”发生,在这种情况下,您实际上希望发生这种效果,所以您需要手动创建它。

编辑以回应更新的问题

好的,所以如果您只需要在某些按钮按下时重置位置,您需要执行以下操作:

首先连接到 BeginRequest 代替/以及:

Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);

这是因为在 args 参数中您可以访问:

args.get_postBackElement().id

它将告诉您启动整个事件的按钮的 id - 然后您可以检查此处的值,移动页面,或将其存储在变量中,并在最终请求中查询它 - 了解竞争条件,等用户在原始更新完成之前单击另一个按钮。

这应该会让你走运 - 在使用 PageRequestManager 事件上有很多例子

于 2009-03-05T20:04:56.620 回答
11

这是在 AJAX 中将滚动条位置重置为 TOP 的完美解决方案

客户端代码

function ResetScrollPosition()
{
    setTimeout("window.scrollTo(0,0)", 0);
}

服务器端代码

ScriptManager.RegisterStartupScript(Page, this.GetType(), "ScrollPage", "ResetScrollPosition();", true);

只有,window.scrollTo(0,0) 不起作用。在这种情况下,Ajax 将优先,因此您必须使用 setTimeout 函数。

于 2009-06-04T15:58:23.127 回答
4

这是我基于此源开发的以下解决方案

ASP.NET 网络表单

<script language="javascript" type="text/javascript">
   function SetScrollEvent() {
      window.scrollTo(0,0);
   }
</script> 

<asp:GridView id="MyGridView" runat="server" OnRowDataBound="MyGridView_OnRowDataBound">
    <Columns>
        <asp:CommandField ButtonType="Link" ShowEditButton="true" />
    </Columns>
</asp:GridView>

背后的 ASP.NET Webform 代码

protected void MyGridView_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    if(e.Row.RowType.Equals(DataControlRowType.DataRow))
    {
        foreach (DataControlFieldCell cell in e.Row.Cells)
        {
            foreach(Control control in cell.Controls)
            {
                LinkButton lb = control as LinkButton;

                if (lb != null && lb.CommandName == "Edit")
                    lb.Attributes.Add("onclick", "SetScrollEvent();");
            }
        }
    }
}
于 2009-03-05T21:22:23.907 回答
2

你在使用 asp.net AJAX 吗?如果是这样,在客户端库 beginRequest 和 endRequest 中有两个非常有用的事件,部分/异步回发的问题之一是,一般页面不知道您在做什么。begin 和 endrequest 事件将允许您在客户端保持滚动位置,您可以在 js 中有一个 var 设置为 beginrequest 上的滚动位置,然后在结束请求时您可以重置您需要的任何元素的 scrollTop ..确实我以前看过这个,但找不到链接。如果我找到一个例子,我会发帖

于 2009-03-05T20:06:35.650 回答
2

取自本教程:

http://aspnet.4guysfromrolla.com/articles/111407-1.aspx

我们设置 MaintainScrollPositionOnPostback=true

然后如果我们需要重置滚动位置调用方法:

Private Sub ResetScrollPosition()
If Not ClientScript.IsClientScriptBlockRegistered(Me.GetType(), "CreateResetScrollPosition") Then
   'Create the ResetScrollPosition() function
   ClientScript.RegisterClientScriptBlock(Me.GetType(), "CreateResetScrollPosition", _
                    "function ResetScrollPosition() {" & vbCrLf & _
                    " var scrollX = document.getElementById('__SCROLLPOSITIONX');" & vbCrLf & _
                    " var scrollY = document.getElementById('__SCROLLPOSITIONY');" & vbCrLf & _
                    " if (scrollX && scrollY) {" & vbCrLf & _
                    "    scrollX.value = 0;" & vbCrLf & _
                    "    scrollY.value = 0;" & vbCrLf & _
                    " }" & vbCrLf & _
                    "}", True)

   'Add the call to the ResetScrollPosition() function
   ClientScript.RegisterStartupScript(Me.GetType(), "CallResetScrollPosition", "ResetScrollPosition();", True)
End If
End Sub 
于 2009-03-07T01:25:11.180 回答
0

您是否设置了页面属性MaintainScrollPosition?不确定如果您执行异步回发是否会有任何不同。

编辑:您可以尝试的一件事是将焦点放在页面顶部附近的特定项目上,这可能会有所帮助并且是一项肮脏的工作。

于 2009-03-05T19:21:04.853 回答
0

我使用了一个名为 hScrollTop 的隐藏输入,它是在 asp.net 表单回发之前设置的。然后,当页面加载时,它会根据隐藏输入的值设置 scrollTop。

在新页面上尝试此代码。

<div style="height:500px"></div>

<form id="Form1" runat=server onsubmit="javascript:saveScrollTop();">
    <input type=submit value="Submit" runat=server>
    <input type="hidden" id="hScrollTop" runat=server>
</form>

<div style="height:1000px"></div>

<script language="javascript">
    function saveScrollTop() {
        document.getElementById("<%= hScrollTop.ClientID %>").value = document.body.scrollTop;
        return true;
    }

    window.onload = function() {
        document.body.scrollTop = document.getElementById("<%= hScrollTop.ClientID %>").value;
    }

</script>
于 2009-03-05T22:02:40.330 回答
0
Page.RegisterStartupScript("MyScript", "<script language=javascript>setTimeout('window.scrollTo(0,0)', 0);</script>");

将上面的内容放在您想要告诉页面顶部的功能中。就像页面无效时一样,拥有它,它会添加临时 javascript 将您带到页面顶部。

于 2012-03-26T16:34:21.207 回答