Pregunta

¿Cuál es la mejor manera de restablecer la posición de desplazamiento a la parte superior de la página después de una devolución de datos asincrónica?

La devolución de datos asincrónica se inicia desde una columna ASP.NET GridView CommandField y el método de actualización del panel de actualización de ASP.NET se llama en el GridView OnRowCommand.

Mi aplicación actual es un sitio web ASP.NET 3.5.

EDITAR: He recibido excelentes comentarios de todos, y terminé usando el método PageRequestManager en una etiqueta de script, pero mi siguiente pregunta es:

¿Cómo lo configuro para que solo se ejecute cuando el usuario hace clic en el campo de control ASP.NET en mi control GridView? Tengo otros botones en la página que realizan una devolución de datos asincrónica que no quiero desplazarme a la parte superior de la página.

EDIT 1: He desarrollado una solución en la que no necesito usar el PageRequestManager. Ver mi respuesta de seguimiento para la solución.

¿Fue útil?

Solución 3

Aquí está la siguiente solución que desarrollé en base a esta fuente

Formulario web 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>

Código de formulario web ASP.NET detrás

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

Otros consejos

A medida que use UpdatePanels, necesitará conectarse a ASP.NET AJAX PageRequestManager

Deberá agregar un método al endRequest ganchos que son:

  

Se genera después de que finaliza una devolución de datos asincrónica y se ha devuelto el control al navegador.

Entonces tendrías algo como:

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

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

Lo que obligará al navegador a desplazarse hacia la parte superior de la página una vez que se haya completado la solicitud de actualización.

Hay otros eventos a los que puedes conectar en lugar del curso:

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

La belleza de los post-back asíncronos es que la página mantendrá la altura de desplazamiento sin que tenga que configurar MaintainScrollPosition, ya que no hay " recarga de página completa " sucede, en este caso, realmente quieres que se produzca ese efecto, por lo que necesitarás crearlo manualmente.

Editar para responder a una pregunta actualizada

Ok, así que si solo necesitas restablecer la posición en ciertas pulsaciones de botones, deberás hacer algo como esto:

Empieza por engancharte a BeginRequest / también:

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

Esto se debe a que en el parámetro args tienes acceso a:

args.get_postBackElement().id

Lo que le indicará la identificación del botón que inició todo el evento; luego puede verificar el valor aquí, mover la página o almacenarla en una variable y consultarla en la solicitud final. condiciones de carrera, etc. donde el usuario hace clic en otro botón antes de que se complete la actualización original.

Eso debería hacerte seguir con suerte: hay algunos ejemplos en torno a Trabajar con eventos de PageRequestManager

Aquí está la solución perfecta para restablecer la posición de la barra de desplazamiento a TOP en AJAX

Código del lado del cliente

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

Código del lado del servidor

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

Solo, window.scrollTo (0,0) no funcionará. Ajax tendrá prioridad en este caso, así que tienes que usar la función setTimeout con eso.

¿Está utilizando asp.net AJAX? Si es así, hay dos eventos muy útiles en las bibliotecas cliente. beginRequest y endRequest, uno de los problemas con las devoluciones de datos parciales / asíncronas, es que la página general no tiene ni idea de lo que está haciendo. los eventos de inicio y finalización le permitirán mantener la posición de desplazamiento en el cliente, podría tener una var in js que esté configurada en la posición de desplazamiento en la solicitud de inicio, luego, al solicitar el fin, puede restablecer el scrollTop del elemento que necesite. Seguro que he visto esto hecho antes, pero no puedo encontrar un enlace. publicar mal si encuentro un ejemplo

tomado de este tutorial:

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

Establecemos MaintainScrollPositionOnPostback = true

Luego, si necesitamos restablecer la posición de desplazamiento, llame al método:

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 

¿Ha establecido la propiedad de página MaintainScrollPosition? No estoy seguro de si sería diferente si realizas una Devolución de Async o no.

Editar: una cosa que puedes intentar es enfocarte en un elemento en particular cerca de la parte superior de tu página, que puede ayudar y ser un trabajo sucio.

Utilizo una entrada oculta llamada hScrollTop que establecí antes de que se devuelva el formulario asp.net. Luego, cuando la página se carga, establece el scrollTop de acuerdo con el valor de la entrada oculta.

Prueba este código en una nueva página.

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

Ponga lo anterior en la función que desea indicar para ir al principio de la página. Como cuando la página no es válida, ten eso ahí y agregará javascript temporal para dispararte a la parte superior de la página.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top