Сброс положения прокрутки после асинхронной обратной передачи - ASP.NET - PullRequest
7 голосов
/ 05 марта 2009

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

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

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

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

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

РЕДАКТИРОВАНИЕ 1: Я разработал решение, в котором мне не нужно использовать PageRequestManager. Смотрите мой ответ для решения.

Ответы [ 8 ]

17 голосов
/ 05 марта 2009

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

11 голосов
/ 04 июня 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.

4 голосов
/ 06 марта 2009

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

ASP.NET Webform

<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();");
            }
        }
    }
}
2 голосов
/ 07 марта 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 
2 голосов
/ 05 марта 2009

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

0 голосов
/ 26 марта 2012
Page.RegisterStartupScript("MyScript", "<script language=javascript>setTimeout('window.scrollTo(0,0)', 0);</script>");

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

0 голосов
/ 06 марта 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>
0 голосов
/ 05 марта 2009

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

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

...