【问题标题】:Reset scroll position after Async postback - ASP.NET异步回发后重置滚动位置 - ASP.NET
【发布时间】:2010-10-11 14:24:39
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

    标签: c# asp.net gridview asp.net-ajax scroll-position


    【解决方案1】:

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

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

    【讨论】:

    • 我只想用 ASP.NET GridView 的这个特定事件返回页面顶部。我在同一页面上有一堆其他按钮,我想保持滚动位置。
    【解决方案2】:

    当您使用 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 - 然后您可以检查此处的值,然后移动页面,或将其存储在变量中,并在最终请求中查询 - 请注意在原始更新完成之前用户单击另一个按钮的竞争条件等。

    这应该会让你走运 - 在 Working with PageRequestManager Events 上有很多关于此的示例

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        下面是我基于这个source开发的解决方案

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

        【讨论】:

          【解决方案5】:

          我使用了一个名为 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>
          

          【讨论】:

            【解决方案6】:

            取自本教程:

            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 
            

            【讨论】:

              【解决方案7】:

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

              客户端代码

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

              服务器端代码

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

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

              【讨论】:

              • 是的,但是如果您只希望在某些事件上发生这种情况,并且只在单击按钮的特定时间发生呢?
              【解决方案8】:
              Page.RegisterStartupScript("MyScript", "<script language=javascript>setTimeout('window.scrollTo(0,0)', 0);</script>");
              

              将上面的内容放到你想告诉的函数到页面顶部。就像页面无效时一样,拥有它,它会添加临时 javascript 将您拍摄到页面顶部。

              【讨论】:

                最近更新 更多