如何在asp.net中实现页面postback后保持滚动位置

8
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="Server">
    <meta http-equiv="refresh" content="4" />   
 <script type="text/javascript">

    var xPos1, yPos1;

    var prm = Sys.WebForms.PageRequestManager.getInstance();
    prm.add_pageLoading(pageLoadingHandler);
    prm.add_pageLoaded(pageLoaded);
    function pageLoaded(sender, args) {

        $get('<%=Panel_Users.ClientID %>').scrollLeft = xPos1;
        $get('<%=Panel_Users.ClientID %>').scrollTop = yPos1;
    }
    function pageLoadingHandler(sender, args) {
        xPos1 = $get('<%=Panel_Users.ClientID %>').scrollLeft
        yPos1 = $get('<%=Panel_Users.ClientID %>').scrollTop;
    }
    </script>
</asp:Content>

无效,我做错了什么。
    <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true"  />    

<div style="height: 504px; width: 941px;">
                 <asp:Panel runat="server" ID="Panel_Users" ScrollBars="Auto" Style="z-index: 1; left: 748px;
                     top: 621px; position: absolute; height: 250px; width: 287px">
                     <asp:UpdatePanel UpdateMode="Conditional" ID="UpdatePanel1" runat="server">
                         <ContentTemplate>
                             <asp:GridView ID="Grid_UserTable" runat="server" Style="z-index: 1; left: 2px; top: 5px;
                                 position: absolute; height: 152px; width: 243px" BorderColor="#666666" AutoGenerateColumns="False"
                                 OnRowDataBound="MyGrid_RowDataBound">
                                 <Columns>
                                     <asp:TemplateField HeaderText="Status">
                                         <ItemTemplate>
                                             <asp:Image ID="Status" runat="server" />
                                         </ItemTemplate>
                                     </asp:TemplateField>
                                     <asp:BoundField DataField="TimeReceived" HeaderText="TimeReceived" InsertVisible="False"
                                         ReadOnly="True" SortExpression="TimeReceived" />
                                     <asp:BoundField DataField="TimeRead" HeaderText="TimeRead" SortExpression="TimeRead" />
                                     <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
                                 </Columns>
                             </asp:GridView>
                         </ContentTemplate>
                     </asp:UpdatePanel>
                 </asp:Panel>
             </div>

我想让页面在每隔5秒刷新后保持在相同的位置,但是页面会回到顶部。我尝试了Page MaintainScrollPositionOnPostback="true" ,但它没有起作用,我尝试使用Ajax,但不知道如何使用。有人可以帮我用Ajax实现吗?

11个回答

23

在您的设计页面上尝试以下代码。 对我来说,它运行良好。

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="frmName.aspx.vb" Inherits="frmName" MaintainScrollPositionOnPostBack = "true" %>

5

1
刚刚测试了MaintainScrollPositionOnPostback页面指令,目前在Firefox 52、Edge 38和Chrome 57中都能正常工作。 - Mike
1
不推荐使用:http://www.ryadel.com/en/asp-net-mantainscrollpositiononpostback-chrome-recent-browsers/ - IrishChieftain

4

<%@ Page MaintainScrollPositionOnPostback="true" %> 这个页面声明将保持滚动位置不变。


4
在“Page_Load”方法中,这个代码可以完美地运行!感谢...Page.MaintainScrollPositionOnPostBack = true; - Pierre
请确保在<form id="form1" runat="server" defaultbutton="YourDefaultButton">不要设置默认按钮。删除defaultbutton="YourDefaultButton",然后MaintainScrollPositionOnPostback="true"就会起作用。 - Vladislav

2

在代码后端尝试以下内容:

protected void Page_Load(object sender, EventArgs e)
{
    if (Page.IsPostBack)
    {
        Page.MaintainScrollPositionOnPostBack = true;
    }
}

附言:我已经用C#试过了。


2

对于听起来很糟糕的用户界面(每5秒刷新一次页面),一个便宜的解决方案是将'#'和要保持可见的元素ID添加到地址栏的URL中,但这会自动滚动到与ID链接的元素的顶部。

如果这是商业产品并且你急需解决问题,我建议使用JQuery的ajax实现,并完全取消重新加载。

这可能只需要一行代码:

  $.ajax(
    {
      url:"/thisPath/requestPath",
      complete:function(data){
      //apply data (the http-response) to HTML
    }
  );

如果这看起来对你来说很奇怪,那只是一个对象文字被传递给 JQuery 对象的 ajax 方法。当 HTTP 响应被接收并作为参数 'data' 传递给函数时,分配给 'complete' 的函数被触发,该参数在 .ajax 方法内部建立。

1

从性能角度来看,UpdatePanels非常糟糕。我会使用jQuery来完成,并完全避免postbacks。

$.ajax({
    url: "/path/to/url/that/returns/users",
    type: "POST",
    dataType: "json",
    data: {},
    success: function(data, status, xhttp)
    {
        var html = "<table>";
        for ( var i = 0; i < data.length; i++ )
        {
            html += "<tr>";
            html += "<td></td>"; // build up table cells
            html += "</tr>";
        }
        html += "</table>";
        $("#NameOfDivToPutTableIn").html(html);
    }

});

如果可以的话,请根据此教程设置要读取的URL。

http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/

如果您不想使用jQuery,仍然可以使用MS AJAX,只需跳过那些更新面板。http://www.geekzilla.co.uk/View7B75C93E-C8C9-4576-972B-2C3138DFC671.htm


0

对于这个问题,网络上有很多答案,但个人来说,它们都没有起作用。因为对我来说,Firefox 会尝试恢复先前的滚动位置(错误),触发 window.scroll 事件,这将用错误的位置覆盖我的隐藏字段,然后我的 scrollTo 就会读取它。 我有一些通过 postbacks 来的 gridviews,然后是自动折叠一些行。

所以这里是另一个解决这个问题的方法 - 我决定只想在提交后而不是刷新后恢复滚动位置,所以这是足够的:

ASPX 页面:

<form runat="server" onsubmit="$('#hfScroll').val($(window).scrollTop()); return true;">
    <input type="hidden" id="hfScroll" value="0" />

Javascript:

function restoreScroll()
{
    var position = parseInt($('#hfScroll').val());
    if (!isNaN(position)) {
        $(document).scrollTop(position);
    }
};
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(restoreScroll);

由于某种原因,在浏览器刷新时我的隐藏输入框没有重置为零,所以有时会表现得很奇怪。我很想知道是什么原因导致这种情况,我认为这可能是 Firefox 的问题,因为在 IE 上不会出现这种情况,但是人生苦短 [他说...已经下载了一半的互联网并花费数小时在此上面..]。


0
对于其他遇到同样问题的人来说,最简单的解决方案是保持整个窗口的滚动位置。
  var xPos, yPos;

    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function (evt, args) {
        window.scrollTo(xPos , yPos);
    });


    Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(function (evt, args) {
        xPos = $(window).scrollLeft();
        yPos = $(window).scrollTop();

    });

在请求的开始和结束处添加代码。在开始请求时使用Jquery获取窗口滚动位置。在结束请求时将页面滚动到该位置。


0

@{
    
}

<html>

<head>
<script type="text/javascript">

window.onload = function () {
   var div = document.getElementById("dvScroll");
   var div_position = document.getElementById("div_position");
    var position = parseInt(@Request.Form("div_position"));
    if (isNaN(position)) {
        position = 0;
    }

    div.scrollTop = position;
    div.onscroll = function () {
        div_position.value = div.scrollTop;
    };
};

</script>
</head>

<body>

<div id="dvScroll" style="overflow-y: scroll; height: 260px; width: 300px">
    1. This is a sample text
    <br />
    2. This is a sample text
    <br />
    3. This is a sample text
    <br />
    4. This is a sample text
    <br />
    5. This is a sample text
    <br />
    6. This is a sample text
    <br />
    7. This is a sample text
    <br />
    8. This is a sample text
    <br />
    9. This is a sample text
    <br />
    10. This is a sample text
    <br />
    11. This is a sample text
    <br />
    12. This is a sample text
    <br />
    13. This is a sample text
    <br />
    14. This is a sample text
    <br />
    15. This is a sample text
    <br />
    16. This is a sample text
    <br />
    17. This is a sample text
    <br />
    18. This is a sample text
    <br />
    19. This is a sample text
    <br />
    20. This is a sample text
    <br />
    21. This is a sample text
    <br />
    22. This is a sample text
    <br />
    23. This is a sample text
    <br />
    24. This is a sample text
    <br />
    25. This is a sample text
    <br />
</div>

<hr />
<form method="post">
<input type="hidden" id="div_position" name="div_position" />
<input type="submit" value="Cool" />
</form> 
</body>
</html>

你可以使用这个来在Postback之后维护滚动位置。
来源:http://www.aspsnippets.com/Articles/Maintain-Scroll-Position-of-DIV-on-PostBack-in-ASPNet.aspx

0
如果是由按钮引起的回传,你可以尝试这个:
ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(button);

你把这个加在哪里? - Jason R
1
我将其添加到 Page_Init 中。 - Khoa Tran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接