c# - Restablecer la posición de desplazamiento después de la devolución de datos de Async-ASP.NET
gridview asp.net-ajax (8)
¿Cuál es la mejor manera de restablecer la posición de desplazamiento en 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 de ASP.NET GridView CommandField y se llama al método de actualización del panel de actualización de ASP.NET en el GridView OnRowCommand.
Mi aplicación actual es un sitio web ASP.NET 3.5.
EDIT: recibí 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 se ejecute solo cuando el usuario hace clic en el campo CommandField de 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 desplazar a la parte superior de la página.
EDIT 1: he desarrollado una solución donde no necesito usar el PageRequestManager. Ver mi respuesta de seguimiento para la solución.
¿Estás usando asp.net AJAX? Si es así, hay dos eventos muy útiles en las bibliotecas del cliente beginRequest y endRequest, uno de los problemas con las devoluciones de datos parciales / asincrónicas es que la página general no tiene ni idea de lo que estás 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 en js que esté configurada en la posición de desplazamiento en beginrequest, y luego en la solicitud final podrá restablecer el scrollTop de cualquier elemento que necesite ... estoy Seguro que he visto esto hecho antes, pero no puedo encontrar un enlace. publicar mal si encuentro un ejemplo
¿Ha establecido la propiedad de página MaintainScrollPosition? No estoy seguro si eso sería diferente si haces una devolución de datos Async o no.
Editar: Una cosa que podría intentar es enfocarse en un elemento en particular cerca de la parte superior de la página, que puede ayudar y ser un trabajo sucio.
Aquí está la siguiente solución que desarrollé basada en esta fuente
Webform de 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();");
}
}
}
}
Utilizo una entrada oculta llamada hScrollTop que configuro antes de que se publique el formulario asp.net. Luego, cuando la página se carga, establece el scrollTop de acuerdo con el valor de la entrada oculta.
Pruebe este código en una página nueva.
<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>
tomado de este tutorial:
http://aspnet.4guysfromrolla.com/articles/111407-1.aspx
Configuramos 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
Aquí está la solución perfecta para restablecer la posición de la barra de desplazamiento en TOP en AJAX
Código del lado del cliente
function ResetScrollPosition()
{
setTimeout("window.scrollTo(0,0)", 0);
}
Código de servidor
ScriptManager.RegisterStartupScript(Page, this.GetType(), "ScrollPage", "ResetScrollPosition();", true);
Solo, window.scrollTo (0,0) no funcionará. Ajax tendrá prioridad en este caso, por lo que debe usar la función setTimeout con eso.
Como está utilizando UpdatePanels, necesitará enganchar en el ASP.NET AJAX PageRequestManager
Deberá agregar un método a los ganchos de evento endRequest que sean:
Se genera después de que se completa una devolución de datos asincrónica y se devuelve 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 cual obligará al navegador a desplazarse de nuevo a la parte superior de la página una vez que se haya completado una solicitud de actualización.
Hay otros eventos en los que podría enganchar en vez de 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 las post-backs asincrónicas es que la página mantendrá la altura de desplazamiento sin tener que establecer MaintainScrollPosition, ya que no hay una "recarga de página completa", en este caso realmente desea que ocurra ese efecto, por lo que necesitará crearlo manualmente
Editar para responder a la pregunta actualizada
De acuerdo, entonces si solo necesita restablecer la posición en ciertas pulsaciones de botones, tendrá que hacer algo como esto:
Comience enganchándose en BeginRequest en su lugar / 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 dirá la identificación del botón que inició todo el evento: puede verificar el valor aquí y mover la página, o almacenarla en una variable, y consultarla en la solicitud final, teniendo en cuenta las condiciones de la carrera. etc. donde el usuario hace clic en otro botón antes de que se complete la actualización original.
Eso debería ayudarlo con algo de suerte. Hay bastantes ejemplos al respecto sobre cómo trabajar con los eventos de PageRequestManager.
Page.RegisterStartupScript("MyScript", "<script language=javascript>setTimeout(''window.scrollTo(0,0)'', 0);</script>");
Coloque lo anterior en la función que desea indicar para ir a la parte superior de la página. Como cuando la página no es válida, póngala allí y agregará javascript temporal para enviarlo a la parte superior de la página.