Сбросить положение прокрутки после асинхронной обратной передачи - ASP.NET

Как лучше всего сбросить позицию прокрутки в начало страницы после асинхронной обратной передачи?

Асинхронная обратная передача инициируется из столбца CommandField ASP.NET GridView, а метод Update панели обновления ASP.NET вызывается в GridView OnRowCommand.

Мое текущее приложение - это веб-сайт ASP.NET 3.5.

РЕДАКТИРОВАТЬ: Я получил отличные отзывы от всех, и я закончил использовать метод PageRequestManager в теге скрипта, но мой следующий вопрос:

Как мне настроить его на выполнение только тогда, когда пользователь щелкает командное поле ASP.NET в моем элементе управления GridView? У меня есть другие кнопки на странице, которые выполняют асинхронную обратную передачу, которую я не хочу прокручивать в верхнюю часть страницы.

ИЗМЕНИТЬ 1: я разработал решение, в котором мне не нужно использовать PageRequestManager. См. Мой последующий ответ для решения.


person Michael Kniskern    schedule 05.03.2009    source источник


Ответы (8)


Поскольку вы используете 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

Что сообщит вам идентификатор кнопки, которая запустила все событие - затем вы можете либо проверить значение здесь, и переместить страницу, либо сохранить его в переменной и запросить его в конечном запросе - зная об условиях гонки, и т.д., где пользователь нажимает другую кнопку до завершения исходного обновления.

Это должно вам помочь - на Работа с События PageRequestManager

person Zhaph - Ben Duguid    schedule 05.03.2009

Вот идеальное решение для сброса положения полосы прокрутки в TOP в AJAX

Клиентский код

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

Код на стороне сервера

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

Только window.scrollTo (0,0) работать не будет. В этом случае приоритет будет иметь Ajax, поэтому вы должны использовать с ним функцию setTimeout.

person Community    schedule 04.06.2009
comment
да, но что, если вы хотите, чтобы это происходило только при определенных событиях и только в определенное время при нажатии кнопки? - person Jack Marchetti; 01.12.2009

Вот следующее решение, которое я разработал на основе этого источника

Веб-форма 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, лежащий в основе

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();");
            }
        }
    }
}
person Michael Kniskern    schedule 05.03.2009

Вы используете asp.net AJAX? Если это так, в клиентских библиотеках есть два очень полезных события beginRequest и endRequest, одна из проблем с частичными / асинхронными обратными передачами заключается в том, что общая страница не имеет представления о том, что вы делаете. события begin и endrequest позволят вам поддерживать позицию прокрутки на клиенте, у вас может быть переменная в js, которая установлена ​​в положение прокрутки в beginrequest, а затем по окончанию запроса вы можете сбросить scrollTop любого элемента, который вам нужен ... я Конечно, я видел это раньше, но не могу найти ссылку. плохой пост, если найду пример

person Matt    schedule 05.03.2009

взято из этого руководства:

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 
person chrisg    schedule 07.03.2009

Вы установили свойство страницы MaintainScrollPosition? Не уверен, будет ли это по-другому, если вы выполняете Async Postback или нет.

Изменить: вы можете попытаться сосредоточить внимание на конкретном элементе в верхней части страницы, что может помочь и оказаться грязной работой.

person TheTXI    schedule 05.03.2009
comment
Я хочу только вернуться в начало страницы с этим конкретным событием ASP.NET GridView. У меня есть несколько других кнопок на той же странице, для которых я хочу сохранить положение прокрутки. - person Michael Kniskern; 05.03.2009

Я использую скрытый ввод под названием 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>
person Community    schedule 05.03.2009

Page.RegisterStartupScript("MyScript", "<script language=javascript>setTimeout('window.scrollTo(0,0)', 0);</script>");

Поместите указанное выше в функцию, которой вы хотите указать, чтобы она перемещалась в верхнюю часть страницы. Например, если страница недействительна, сделайте это там, и он добавит временный javascript, чтобы вы переместились в верхнюю часть страницы.

person Dmitriy    schedule 26.03.2012