How do I maintain scroll position in MVC?

后端 未结 12 1891
情歌与酒
情歌与酒 2020-11-27 18:02

Im working on a project in MVC and have enjoyed learning about it. There are a few growing pains but once you figure them out it\'s not bad. One thing that is really simpl

相关标签:
12条回答
  • 2020-11-27 18:22

    I use .scrollTop like shown below, very easy, it even works with multiple forms in the view (I have a very long view, broken down into multiple forms):

    First put this property inside the model:

                   public string scrollTop { get; set; }
    

    And in the view, inside Form #1:

                   @Html.HiddenFor(m => m.scrollTop, new {@id="ScrollForm1"})
    

    inside Form #2:

                   @Html.HiddenFor(m => m.scrollTop, new {@id="ScrollForm2"})
    

    inside Form #2:

                   @Html.HiddenFor(m => m.scrollTop, new {@id="ScrollForm3"})
    

    and then at the bottom of the view:

     $(document).ready(function () {
        $(document).scrollTop(@Model.scrollTop);
        $(document).scroll(function () {
            $("#ScrollForm1").val($(document).scrollTop());
            $("#ScrollForm2").val($(document).scrollTop());
            $("#ScrollForm3").val($(document).scrollTop());
          });
       });
    

    Your scroll position is always preserved upon postback because the @Html.HiddenFor fields store your current scroll and pass it to the model on post. And then, when the page comes up it gets the scrollTop value from the model. At the end your page would behave like webform, everything stays intact.

    0 讨论(0)
  • 2020-11-27 18:23

    @{
    
    }
    
    <html>
    
    <head>
        <script type="text/javascript">
    
    window.onload = function () {
        var div = document.getElementById("dvScroll");
       var div_position = document.getElementById("div_position");
        var position = parseInt(@Request.Form("div_position"));
        if (isNaN(position)) {
            position = 0;
        }
    
        div.scrollTop = position;
        div.onscroll = function () {
            div_position.value = div.scrollTop;
        };
    };
    
    </script>
    </head>
    
    <body>
    
    <div id="dvScroll" style="overflow-y: scroll; height: 260px; width: 300px">
    
        1. This is a sample text
    
        <br />
    
        2. This is a sample text
    
        <br />
    
        3. This is a sample text
    
        <br />
    
        4. This is a sample text
    
        <br />
    
        5. This is a sample text
    
        <br />
    
        6. This is a sample text
    
        <br />
    
        7. This is a sample text
    
        <br />
    
        8. This is a sample text
    
        <br />
    
        9. This is a sample text
    
        <br />
    
        10. This is a sample text
    
        <br />
    
        11. This is a sample text
    
        <br />
    
        12. This is a sample text
    
        <br />
    
        13. This is a sample text
    
        <br />
    
        14. This is a sample text
    
        <br />
    
        15. This is a sample text
    
        <br />
    
        16. This is a sample text
    
        <br />
    
        17. This is a sample text
    
        <br />
    
        18. This is a sample text
    
        <br />
    
        19. This is a sample text
    
        <br />
    
        20. This is a sample text
    
        <br />
    
        21. This is a sample text
    
        <br />
    
        22. This is a sample text
    
        <br />
    
        23. This is a sample text
    
        <br />
    
        24. This is a sample text
    
        <br />
    
        25. This is a sample text
    
        <br />
    
    </div>
    
    <hr />
    <form method="post">
    <input type="hidden" id="div_position" name="div_position" />
    <input type="submit" value="Cool" />
        </form> 
    </body>
    </html>

    You can use this to maintain scroll Position after postback.

    Source: http://www.aspsnippets.com/Articles/Maintain-Scroll-Position-of-DIV-on-PostBack-in-ASPNet.aspx

    0 讨论(0)
  • 2020-11-27 18:27

    Actually there is no standard way of handling this, this was a Microsoft hack to support their post back model. They needed this because every control did a post back and the user would constantly be pushed back to the top of the page.

    The recommendation for use with MVC is to do most of your post back to servers using AJAX. So that the page doesn't have to rerender the the focus is not moved. jQuery makes AJAX really easy, and there is even default forms like

    <% Ajax.BeginForm(...) %>
    

    Which will take care of the AJAX side of things for you.

    0 讨论(0)
  • 2020-11-27 18:34

    Taking inspiration from WebForms and the answer provided by Richard Gadsden, another approach using javascript and the form collection could look something like this:

    @{
        var scrollPositionX = string.Empty;        
        if(IsPost) {
            scrollPositionX = Request.Form["ScrollPositionX"];
        }
    }
    
    <form action="" method="post">
        <input type="hidden" id="ScrollPositionX" name="ScrollPositionX" value="@scrollPositionX" />
        <input type="submit" id="Submit" name="Submit" value="Go" />
    </form>
    
    $("#Submit").click(function () {
        $("#ScrollPositionX").val($(document).scrollTop());
    });
    
    $("#ScrollPositionX").each(function () {
        var val = parseInt($(this).val(), 10);
        if (!isNaN(val))
            $(document).scrollTop(val);
    });
    

    The code provided is for inspiration and is in no way prettified. It could probably be done in a few different ways, I guess it all comes down to how you decide to persist the scrollTop value of your document across the POST. It is fully working and should be cross browser safe since we are using jQuery to do the scrolling. I believe the code provided is self-explanatory, but I will be happy to provide a more detailed description on whats going on, just let me know.

    0 讨论(0)
  • 2020-11-27 18:35

    My own workaround is using some info in the ViewData to know what area must be shown in the backnavigation, and a little javascript to position the page's cursor:

    In the View, an element like this:

    <h3 id="tasks">
        Contained tasks
    </h3>
    

    And the javascript to repositionate the page:

    <script type="text/javascript">
        addOnLoad(goAnchor);
    
        function goAnchor() {
            var paging = <%= //Here you determine (from the ViewData or whatever) if you have to position the element %>;
            if (paging == "True") {
                window.location.hash = "tasks";
            }
    </script>
    

    You could use a switch to determine what element from the view page you must relocate.

    Hope it helps.

    0 讨论(0)
  • 2020-11-27 18:38

    I've resolved this in JS :

    $(document).scroll(function(){
        localStorage['page'] = document.URL;
        localStorage['scrollTop'] = $(document).scrollTop();
    });
    

    Then in document ready :

    $(document).ready(function(){
        if (localStorage['page'] == document.URL) {
            $(document).scrollTop(localStorage['scrollTop']);
        }
    });
    
    0 讨论(0)
提交回复
热议问题