Domanda

Qual è il modo migliore per ripristinare la posizione di scorrimento nella parte superiore della pagina dopo un postback asincrono?

Il postback asincrono viene avviato da una colonna CommandField di ASP.NET GridView e il metodo di aggiornamento del pannello di aggiornamento ASP.NET viene chiamato in GridView OnRowCommand.

La mia attuale applicazione è un sito Web ASP.NET 3.5.

EDIT: Ho ricevuto un feedback eccellente da tutti e ho finito di utilizzare il metodo PageRequestManager in un tag di script, ma la mia prossima domanda è:

Come si configura per l'esecuzione solo quando l'utente fa clic su CommandField ASP.NET nel mio controllo GridView? Ho altri pulsanti sulla pagina che eseguono un postback asincrono che non voglio scorrere fino all'inizio della pagina.

EDIT 1: Ho sviluppato una soluzione in cui non è necessario utilizzare PageRequestManager. Vedi la mia risposta di follow-up per la soluzione.

È stato utile?

Soluzione 3

Ecco la seguente soluzione che ho sviluppato sulla base di questa fonte

Modulo 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>

Codice ASP.NET Webform dietro

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

Altri suggerimenti

Quando usi UpdatePanels dovrai collegarti ad ASP.NET AJAX PageRequestManager

Dovrai aggiungere un metodo all'evento endRequest ganci che sono:

  

Generato dopo che un postback asincrono è terminato e il controllo è stato restituito al browser.

Quindi avresti qualcosa del tipo:

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

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

Che costringerà il browser a tornare all'inizio della pagina una volta completata una richiesta di aggiornamento.

Ci sono altri eventi a cui puoi agganciare invece ovviamente:

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 bellezza dei post-back asincroni è che la pagina manterrà l'altezza di scorrimento senza che tu debba impostare MaintainScrollPosition, in quanto non è presente "ricarica pagina intera" in questo caso, in realtà vuoi che si verifichi quell'effetto, quindi dovrai crearlo manualmente.

Modifica per rispondere alla domanda aggiornata

Ok, quindi se devi reimpostare la posizione solo premendo determinati pulsanti dovrai fare qualcosa del genere:

Inizia collegando BeginRequest invece / pure:

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

Questo perché nel parametro args puoi accedere a:

args.get_postBackElement().id

Il che ti dirà l'id del pulsante che ha avviato l'intero evento - puoi quindi controllare il valore qui, spostare la pagina o memorizzarlo in una variabile e interrogarlo nella richiesta finale - tenendo presente condizioni di gara, ecc. in cui l'utente fa clic su un altro pulsante prima del completamento dell'aggiornamento originale.

Ciò dovrebbe farti andare avanti con un po 'di fortuna - ci sono alcuni esempi al riguardo su Lavorare con gli eventi PageRequestManager

Ecco la soluzione perfetta per ripristinare la posizione della barra di scorrimento su TOP in AJAX

Codice lato client

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

Codice lato server

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

Solo window.scrollTo (0,0) non funzionerà. Ajax avrà la precedenza in questo caso, quindi devi usare la funzione setTimeout con quella.

Stai usando asp.net AJAX? In tal caso, ci sono due eventi molto utili nelle librerie client beginRequest e endRequest, uno dei problemi con i postback parziali / asincroni, è che la pagina generale non ha idea di cosa stai facendo. gli eventi di inizio e di fine corsa ti permetteranno di mantenere la posizione di scorrimento sul client, potresti avere una var in js che è impostata sulla posizione di scorrimento su richiesta di inizio, quindi su richiesta finale puoi resettare qualunque scorrimento dell'elemento. sicuramente l'ho già visto prima ma non riesco a trovare un link. post male se trovo un esempio

tratto da questo tutorial:

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

Impostiamo MaintainScrollPositionOnPostback = true

Quindi, se è necessario ripristinare la posizione di scorrimento, chiamare il metodo:

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 

Hai impostato la proprietà della pagina MaintainScrollPosition? Non sono sicuro che sarebbe diverso se si esegue un postback asincrono o meno.

Modifica: una cosa che potresti tentare è quella di focalizzare l'attenzione su un particolare elemento nella parte superiore della pagina, che può essere d'aiuto ed essere un lavoro sporco.

Uso un input nascosto chiamato hScrollTop che ho impostato prima che il modulo asp.net sia posticipato. Quindi, quando la pagina viene caricata, imposta scrollTop in base al valore dell'input nascosto.

Prova questo codice in una nuova pagina.

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

Metti quanto sopra alla funzione che vuoi dire per andare all'inizio della pagina. Come quando la pagina non è valida, disponila lì e aggiungerà javascript temporaneo per spararti in cima alla pagina.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top