简体   繁体   English

异步回发后重置滚动 position - ASP.NET

[英]Reset scroll position after Async postback - ASP.NET

What is the best way to reset the scroll position to the top of page after the an asynchronous postback?异步回发后将滚动 position 重置到页面顶部的最佳方法是什么?

The asynchronous postback is initiated from a ASP.NET GridView CommandField column and the ASP.NET update panel Update method is called in the GridView OnRowCommand.异步回发从 ASP.NET GridView CommandField 列和 ASP.NET 更新面板启动 ZBB404EDC3A078A49DZBB404EDC3A078D49DZB404EDC3A078DZ 更新面板。

My current application is an ASP.NET 3.5 web site.我当前的应用程序是 ASP.NET 3.5 web 站点。

EDIT: I have received excellent feedback from everyone, and I ended using the PageRequestManager method in a script tag, but my next question is:编辑:我收到了大家的优秀反馈,我结束了在脚本标签中使用 PageRequestManager 方法,但我的下一个问题是:

How do I configure it to only execute when the user clicks the ASP.NET CommandField in my GridView control?如何将其配置为仅在用户单击 GridView 控件中的 ASP.NET CommandField 时执行? I have other buttons on the page that perform an asynchronous postback that I do not want to scroll to the top of the page.我在页面上有其他按钮执行异步回发,我不想滚动到页面顶部。

EDIT 1: I have developed a solution where I do not need to use the PageRequestManager.编辑 1:我开发了一个不需要使用 PageRequestManager 的解决方案。 See my follow up answer for solution.请参阅我的后续答案以获取解决方案。

As you're using UpdatePanels you're going to need to hook into the ASP.NET AJAX PageRequestManager当您使用 UpdatePanels 时,您需要连接到 ASP.NET AJAX PageRequestManager

You'll need to add a method to the endRequest event hooks that are:您需要向endRequest事件挂钩添加一个方法,这些挂钩是:

Raised after an asynchronous postback is finished and control has been returned to the browser.在异步回发完成并将控制权返回给浏览器后引发。

So you'd have something like:所以你会有类似的东西:

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

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

Which will force the browser to scroll back to the top of the page once an update request has completed.一旦更新请求完成,这将强制浏览器滚动回页面顶部。

There are other events you could hook into instead of course:当然,您还可以加入其他事件:

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

The beauty of asynchronous post-backs is that the page will maintain the scroll height without you having to set MaintainScrollPosition, as there is no "full page reload" happening, in this case you actually want that effect to happen, so you will need to manually create it.异步回发的美妙之处在于页面将保持滚动高度而无需您设置 MaintainScrollPosition,因为没有“整页重新加载”发生,在这种情况下,您实际上希望发生这种效果,所以您需要手动创建它。

Edit to respond to updated question编辑以回应更新的问题

Ok, so if you need to only reset the postion on certain button presses you'll need to do something like this:好的,所以如果您只需要在某些按钮按下时重置位置,您需要执行以下操作:

Start by hooking into the BeginRequest instead/as well:首先连接到 BeginRequest 代替/以及:

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

This is because in the args parameter you get access to:这是因为在 args 参数中您可以访问:

args.get_postBackElement().id

Which will tell you the id of the button that started the whole event - you can then either check the value here, and move the page, or store it in a variable, and query it in the end request - being aware of race conditions, etc where the user clicks another button before your original update completes.它将告诉您启动整个事件的按钮的 ID - 然后您可以检查此处的值,移动页面,或将其存储在变量中,并在最终请求中查询它 - 了解竞争条件,等用户在原始更新完成之前单击另一个按钮。

That should get you going with any luck - there's quite a few examples around this on Working with PageRequestManager Events这应该会让你走运 - 在使用 PageRequestManager 事件上有很多例子

Here is the perfect solution to reset scroll bar position to TOP in AJAX这是在 AJAX 中将滚动条 position 重置为 TOP 的完美解决方案

Client Side Code客户端代码

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

Server Side Code服务器端代码

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

Only,window.scrollTo(0,0) will not work.只有 window.scrollTo(0,0) 不起作用。 Ajax will take precedence in this case so you have to use setTimeout function with that.在这种情况下 Ajax 将优先,因此您必须使用 setTimeout function 。

Here is the following solution I developed based on this source这是我基于此开发的以下解决方案

ASP.NET Webform 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 code behind 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();");
            }
        }
    }
}

Are you using asp.net AJAX?您使用的是 asp.net AJAX 吗? If so there are two very useful events in the client libraries beginRequest and endRequest, one of the problems with partial/async postbacks, is that the general page hasnt got a clue what you are doing.如果是这样,在客户端库 beginRequest 和 endRequest 中有两个非常有用的事件,部分/异步回发的问题之一是,一般页面不知道您在做什么。 the begin and endrequest events will allow you to maintain scroll position at the client, you could have a var in js that is set to the scroll position on beginrequest, then on end request you can reset whichever element's scrollTop you require.. i'm sure ive seen this done before but cant find a link. begin 和 endrequest 事件将允许您在客户端维护滚动 position,您可以在 js 中有一个 var 设置为 beginrequest 上的滚动 position,然后在结束请求时您可以重置您需要的任何元素的 scrollTop..确实我以前看过这个,但找不到链接。 ill post if i find an example如果我找到一个例子,我会发帖

taken from this tutorial:取自本教程:

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

We set MaintainScrollPositionOnPostback=true我们设置 MaintainScrollPositionOnPostback=true

Then if we need to reset scroll position call the method:然后如果我们需要重置滚动 position 调用方法:

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 

Have you set the page property MaintainScrollPosition?您是否设置了页面属性MaintainScrollPosition? Not sure if that would be any different if you do an Async Postback or not.不确定如果您执行异步回发是否会有任何不同。

Edit: One thing you could attempt is to set focus on a particular item near the top of your page, that may help and be a dirty work around.编辑:您可以尝试的一件事是将焦点放在页面顶部附近的特定项目上,这可能会有所帮助并且是一项肮脏的工作。

I use a hidden Input called hScrollTop that I set before the asp.net Form is posted back.我使用了一个名为 hScrollTop 的隐藏输入,我在回发 asp.net 表单之前设置了该输入。 Then, when the page loads, it sets the scrollTop according to the hidden input's value.然后,当页面加载时,它会根据隐藏输入的值设置 scrollTop。

Try this code on a new page.在新页面上尝试此代码。

<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>
Page.RegisterStartupScript("MyScript", "<script language=javascript>setTimeout('window.scrollTo(0,0)', 0);</script>");

Put the above to the function that you want to tell to go to the top of page.把上面的 function 你想告诉 go 到页面顶部。 Like when the page is not valid, have that there and it will add temporary javascript to shoot you to the top of the page.就像页面无效时一样,拥有它,它会添加临时 javascript 将您带到页面顶部。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM