Taghelper Scrollposition wieder herstellen

In meinem letzten Blog Post zu MaintainScrollPosition habe ich die Grundlagen per JavaScript erarbeitet. Eine Website soll egal ob refresh oder Postback dem Benutzer die gleiche Stelle zeigen wie vorher. Also wohin man gescrollt ist. Folgende Lösung für ASP.NET 7 Razor Pages.

Per einfachen Tag Helper in der Scripts Sektion soll das Feature Position im Browser wieder herstellen aktiviert sein.

@section Scripts {  <ScrollPosition></ScrollPosition> }

 

Dazu erstellt man im Visual Studio ASP.NET Projekt eine Klasse die von TagHelper erbt und definiert das zukünftige HTML Element oder auch ggf Attribut. Dazu wird per Schraubenziehersymbol die Überschreibung generiert.

taghelper1

Der konzeptionelle C# Code definiert in Zeile 1 das <ScrollPosition> und in Zeile 6 die gerenderte Ausgabe.

   1:   [HtmlTargetElement("ScrollPosition", 
TagStructure = TagStructure.Unspecified)]
   2:   public class MaintainScrollposition : TagHelper
   3:   {
   4:       public override void Process(
TagHelperContext context, TagHelperOutput output)
   5:       {
   6:           output.PostContent.Append("<script>");
   7:       }
   8:   }

Wer diesen Code probiert wird erkennen, das die HTML Entitys statt der <> im HTML Code erscheinen. Das Problem lässt sich mit AppendHTML lösen. Nächste Herausforderung: Wie lese ich den Wert der Form Elemente aus.

Reminder: die Wiederherstellung der Scroll Position, erfolgt über ein per JavaScript dynamisch zum Form das den Post auslöst, hinzugefügtes Input Element.

Dazu dient der ViewContext, der wiederum Zugriff auf den HTTPContext liefert und somit auf den Request und das Formular.

Also zunächst für das Verständnis der Code um die die Scroll Methode (ident zu ScrollTo) zu setzen.

   1:[HtmlTargetElement("ScrollPosition", TagStructure = TagStructure.Unspecified)]
   2:public class ScrollPositionTagHelper : TagHelper
   3:    {
   4:  [ViewContext]
   5:  public ViewContext ViewContext { get; set; }
   6:        public override void Process(TagHelperContext context, 
TagHelperOutput output)
   7:   {
   8:    float scrollpos = 0;
   9:    if (ViewContext.HttpContext.Request.HasFormContentType)
  10:    {
  11:     scrollpos = float.Parse(
ViewContext.HttpContext.Request.Form["scrollpos"], CultureInfo.CurrentCulture);
  12:    }
  13:    output.PostContent.AppendHtml("<script>");  
  14:   if (scrollpos > 0)
  15:    {
  16:       output.PostContent.AppendHtml($"
window.scroll({{top: {scrollpos.ToString("
0.0", CultureInfo.InvariantCulture)},
left: 0, behavior: 'instant'}});"
);
  17:            }
  18:  output.PostContent.AppendHtml("</script>");
  19:        }
  20:    }

 

Das rendert dann, wenn gescrollt, das JavaScript in der Page, wie im anderen Blog Post beschrieben.

scroll2

Aber noch fehlt der Teil, der das INPUT in den DOM unterhalb des FORM höngt und mit der ScrollY Position füllt. Hier ist es einfacher den JavaScriipt Code in einen Single Block zu hängen. Auch eine .JS Datei zu laden, sehe ich als Option. Dieser Code als Ergänzung zum vorigen c# Listing nach Zeile 13.

   1:   var js = @"  document.addEventListener('DOMContentLoaded', function (event) {
   2:   window.onsubmit = function (event) {
   3:      var input = document.createElement('input');
   4:      input.name = 'scrollpos';
   5:      input.id = 'scrollpos';
   6:      input.value = this.scrollY.toLocaleString();
   7:      input.type = 'hidden';
   8:      event.target.appendChild(input);
   9:  };});";
  10:  ...
  11:  output.PostContent.AppendHtml("<script>");  
  12:  output.PostContent.AppendHtml(js);

 

Das wars schon.

Kommentare sind geschlossen