ASP.net Postback - Scroll to Specific Position

后端 未结 9 1020
天命终不由人
天命终不由人 2020-12-15 16:50

I have an ASP.net WebForms page that has a lot of content on the top of the screen. It has a link button that will post back to the page and show another section of the page

相关标签:
9条回答
  • 2020-12-15 17:22

    While not elegant for your situation, it is also possible to use dummy Custom Validators, set the one you want to scroll to as invalid then do

    DummyCustomValidator.SetFocusOnError = true;
    

    In my case, I am actually using page Validators with async postbacks and multiple programmatically shown/hidden panels on a long vertical form. Since some fields are only required if MyLogicalParent.Visible = true and if specific answers are given in other controls, such as a RequiredFieldValidator on a TextBox when "Other" is selected in a CheckBoxList, I have a LOT of logic to process page validation. Setting scroll positions was painful in all of the normal methods.

    I also use RegisterStartupScript to handle maintaining the current scroll position when async postbacks alter the page's vertical dimension.

        <script type="text/javascript">
            $(document).ready(function () {
                var windowHeight = $(document)[0].documentElement.clientHeight;    /*This is the height of the viewable browser area.*/
                var scrolledPosition = $(window)[0].scrollY;                       /*This is the number of Pixels the Window is currently scrolled to.*/
                var scroll = windowHeight + scrolledPosition;                       /*This should be the same as $(window).scrollTop() */
                /*If the amount scrolled + the height of the window is Less than or equal to the total height of the page (past the viewable client window)*/
                if ($(window).scrollTop() + getWindowSize()[1] <= getDocHeight()) {
                    /*Move the morescroll div to the bottom of the page... -34 is the height of the div plus a small bottom margin.*/
                    $("#morescroll").offset({ top: windowHeight - 34 });
                }
            })
    
            /*This is the total height of the document including the area past the viewable client window.*/
            function getDocHeight() {
                var D = document;
                /*The Largest of these six numbers is the total doc height. */
                return Math.max(
                    D.body.scrollHeight, D.documentElement.scrollHeight,
                    D.body.offsetHeight, D.documentElement.offsetHeight,
                    D.body.clientHeight, D.documentElement.clientHeight
                );
            }
    
            /*This is the width and height of the Viewable Browser area.*/
            function getWindowSize() {
                var myWidth = 0, myHeight = 0;
                if (typeof (window.innerWidth) == 'number') {
                    //Non-IE
                    myWidth = window.innerWidth;
                    myHeight = window.innerHeight;
                } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
                    //IE 6+ in 'standards compliant mode'
                    myWidth = document.documentElement.clientWidth;
                    myHeight = document.documentElement.clientHeight;
                } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
                    //IE 4 compatible
                    myWidth = document.body.clientWidth;
                    myHeight = document.body.clientHeight;
                }
                return [myWidth, myHeight];
            }
    
            //This sets a transparent div <div id="morescroll" class="scrollMinder"> with the text "Scroll down for more." to the bottom of the viewable page. 
            $(window).scroll(
                function () {
                    var windowHeight = $(document)[0].documentElement.clientHeight;
                    var scrolledPosition = $(window)[0].scrollY;
                    var scrll = windowHeight + scrolledPosition;
                    document.getElementById('<%= HF_LastScrolled.ClientID %>').value = scrolledPosition;
                    var docHeight = $(document)[0].documentElement.scrollHeight;
                    /*if we are scrolled to within 60 pixels from the bottom of the document, hide the indicator so it doesn't cover the footer.*/
                    if ($(window).scrollTop() + $(window).height() >= $(document).height() - 60) {
                        $("#morescroll").hide();
                    }
                    /*if we scroll back above 60 pixels from the bottom of the document, show the indicator and set the top of the div to -34 pixels.*/
                    else if ($(window).scrollTop() + getWindowSize()[1] <= getDocHeight()) {
                        $("#morescroll").show();
                        $("#morescroll").offset({ top: scrll - 34 });
                    }
                });
    </script>
    
         <%-- This stores the Y scroll location.--%>
            <asp:HiddenField ID="HF_LastScrolled" runat="server" />
            <div id="morescroll" class="scrollMinder">
                <span class="spanMinder">Scroll down for more.</span>
            </div>
    
    
    
    
    
     private string LastScrolled = "";
    
        protected void Page_PreRender (object sender, EventArgs e)
                {
                    if (string.IsNullOrEmpty(LastScrolled))
                    {
                        LastScrolled = "0";
                    }
                    if (string.IsNullOrEmpty(scrollPosition))
                    {
                        sb.Clear();
                        sb.AppendLine("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);");
                        sb.AppendLine("function EndRequestHandler(sender, args) {");
                        sb.Append("scrollTo(0, ").Append(LastScrolled).Append(");");
                        sb.AppendLine("}");
                        sb.AppendLine("function load() {");
                        sb.AppendLine("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);");
                        sb.AppendLine("}");
                        cs.RegisterStartupScript(GetType(), "ScrollToLastPosition", sb.ToString(), true);
                        scrollPosition = "ScrollToLastPosition";
                    }
                    if (!string.IsNullOrEmpty(scrollPosition))
                    {
                        ScriptManager.RegisterStartupScript(this, GetType(), scrollPosition, sb.ToString(), true);
                    }
                }
    
        protected void Page_Load (object sender, EventArgs e)
                {
                  LastScrolled = HF_LastScrolled.Value;
                  Page.MaintainScrollPositionOnPostBack = false;
                }
    
       protected void SetScrollToLastPosition ()
                {
                    sb.Clear();
                    sb.AppendLine("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);");
                    sb.AppendLine("function EndRequestHandler(sender, args) {");
                    sb.Append("scrollTo(0, ").Append(LastScrolled).AppendLine(");");
                    sb.AppendLine("}");
                    sb.AppendLine("function load() {");
                    sb.AppendLine("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);");
                    sb.AppendLine("}");
                    cs.RegisterStartupScript(GetType(), "ScrollToLastPosition", sb.ToString(), true);
                    scrollPosition = "ScrollToLastPosition";
                    string tempstring = sb.ToString();
                    ScriptManager.RegisterStartupScript(this, GetType(), scrollPosition, sb.ToString(), true);
                }
    
    protected void SetScrolltoPositionY (int y)
                {
                    sb.Clear();
                    sb.AppendLine("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);");
                    sb.AppendLine("function EndRequestHandler(sender, args) {");
                    sb.Append("scrollTo(0, ").Append(y).AppendLine(");");
                    sb.AppendLine("}");
                    sb.AppendLine("function load() {");
                    sb.AppendLine("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);");
                    sb.AppendLine("}");
                    cs.RegisterStartupScript(GetType(), "ScrollTo-0-" + y.ToString(), sb.ToString(), true);
                    scrollPosition = "ScrollTo - 0-" + y.ToString();
                    string tempstring = sb.ToString();
                    ScriptManager.RegisterStartupScript(this, GetType(), scrollPosition, sb.ToString(), true);
                }
    
    0 讨论(0)
  • 2020-12-15 17:27

    try this

    protected void Page_Load(object sender, EventArgs e)
        {
            if (Page.IsPostBack) {
                string targetId = Page.Request.Params.Get("__EVENTTARGET");
                Page.ClientScript.RegisterStartupScript(this.GetType(), "focusthis", "document.getElementById('" + targetId + "').focus()", true);
    
            }
        }
    
    0 讨论(0)
  • 2020-12-15 17:28

    I've tried Matthieu Charbonnier answer, but it didn't work unless I've added

    " window.scrollTo = function () { };" 
    

    as it was suggested in http://gnidesign.blogspot.com.au/2011/06/how-to-maintain-page-scroll-on-postback.html

    I've created a helper method, that's working in Chrome,FireFox and IE

    public static void ScrollToControl( Page page, string clientId, bool alignToTop)
     {
         //NOTE: if there are more than one call on the page, first one will take preference
         //If we want that last will take  preference, change key from MethodBase.GetCurrentMethod().Name to anchorName
         //recommended in http://gnidesign.blogspot.com.au/2011/06/how-to-maintain-page-scroll-on-postback.html              
         String script = " window.scrollTo = function () { };" + Environment.NewLine;
         script += String.Format("document.getElementById('{0}').scrollIntoView({1});" , clientId, alignToTop.JSToString());
         page.ClientScript.RegisterStartupScript(TypeForClientScript(), MethodBase.GetCurrentMethod().Name, script, true );
         //return script;
     }
     public static string JSToString(this bool bValue)
     {
         return bValue.ToString().ToLower();
     }
    

    Use getElementById('{0}').scrollIntoView is simpler than location.hash , because you don't need to add extra anchor element.

    Parameter alignToTop is very convenient to specify do you want to show control at the top or bottom of the screen.

    0 讨论(0)
提交回复
热议问题