按下后退按钮时如何保留可滚动区域的滚动位置?

How can I retain the scroll position of a scrollable area when pressing back button?

我在一个大的可滚动 div 中有一长串 link。每次当用户单击 link 然后单击后退按钮时,它会从 div 的最顶部开始。它对我们的用户不友好。有什么方法可以让浏览器在按下后退按钮时滚动到上一个位置?

非常感谢!

在页面卸载期间,获取滚动位置并将其存储在本地存储中。然后在页面加载期间,检查本地存储并设置滚动位置。假设您有一个 ID 为 element 的 div 元素。如果是页面,请更改选择器:)

$(function() {
   $(window).unload(function() {
      var scrollPosition = $("div#element").scrollTop();
      localStorage.setItem("scrollPosition", scrollPosition);
   });
   if(localStorage.scrollPosition) {
      $("div#element").scrollTop(localStorage.getItem("scrollPosition"));
   }
});

如果后退按钮是一种历史后退按钮 window.history.back() 那么您正在寻找的是默认浏览器功能。所以你不用担心。

如果您的后退按钮实际上通过 link 或表单指向应用程序中的某个 URL,那么您必须手动处理。

对于解决方案,您可以使用 cookie 来存储您的页面滚动值。每次用户在您的页面上滚动时,将该页面的滚动值保存到 cookie。额外的工作应用于手动 cookie 管理。

window.onScroll = function(){
    document.cookie="pageid=foo-"+window.scrollY+";";
}

此 cookie 值可用于设置页面访问时页面的滚动值。

window.scroll(0,cookievalue);

我在使用由固定菜单 div 和滚动文档 div(下面代码示例中的 "pxeMainDiv")组成的简单用户界面时遇到了同样的问题。以下解决方案适用于 Chrome 47.0.2526.106 m 和 Firefox 43.0.3。 (我的应用是为了使用in-house,我不需要迎合旧版本的IE)。

$(document).ready(function(){
    if (history.state) {
       $("#pxeMainDiv").scrollTop(history.state.data);
    }
    $("#pxeMainDiv").scroll(function() {
       var scrollPos = $("#pxeMainDiv").scrollTop();
       var stateObj = { data: scrollPos };
       history.replaceState(stateObj, "");
    });
});

在div滚动事件中,div的滚动位置存储在浏览器历史记录对象中的状态对象中。在按下返回按钮后,在文档就绪事件中,div 的滚动位置将恢复为从 history.state 对象检索到的值。

此解决方案适用于任意长链接链的反向导航。

文档在这里:https://developer.mozilla.org/en-US/docs/Web/API/History_API

我认为我们应该保存每页的滚动数据,而且我们应该使用会话存储而不是本地存储,因为会话存储只影响当前选项卡,而本地存储在所有选项卡和同源 windows 之间共享

$(function () {
            var pathName = document.location.pathname;
            window.onbeforeunload = function () {
                var scrollPosition = $(document).scrollTop();
                sessionStorage.setItem("scrollPosition_" + pathName, scrollPosition.toString());
            }
            if (sessionStorage["scrollPosition_" + pathName]) {
                $(document).scrollTop(sessionStorage.getItem("scrollPosition_" + pathName));
            }
        });

使用 window.history.back() 时,这实际上是浏览器的默认功能

在我目前正在建设的网站上,我希望将公司的徽标反向链接到索引页面。由于jQuery3,$(window).unload(function()应该改写为$(window).on('unload', function()。我的代码如下所示(使用 Kirby CMS 的 php 语法):

<?php if ($page->template() == 'home'): ?>

<script>

$(function() {
 $(window).on("unload", function() {
    var scrollPosition = $(window).scrollTop();
    localStorage.setItem("scrollPosition", scrollPosition);
 });
 if(localStorage.scrollPosition) {
    $(window).scrollTop(localStorage.getItem("scrollPosition"));
 }
});

</script>

使用 History api 您可以利用 scrollRestoration 并阻止浏览器重置滚动位置。

在这里阅读。 https://developers.google.com/web/updates/2015/09/history-api-scroll-restoration

对于来自 React 或类似 React Router 的任何人,这里有两个简单的函数:

export function saveScrollPosition(context: any) {
  let path = context.router.route.location.pathname;
  let y = window.scrollY;
  sessionStorage.setItem("scrollPosition_" + path, y.toString());
}

export function restoreScrollPosition(context: any) {
  let path = context.router.route.location.pathname;
  let y = Number(sessionStorage.getItem("scrollPosition_" + path));
  window.scrollTo(0, y);
}

/* 使用下面的代码恢复单个项目的滚动位置并将焦点设置到最后单击的项目。 */

(function ($)
{

    if (sessionStorage)
        $.fn.scrollKeeper = function (options)
        {
            var defauts =
            {
                key: 'default'
            };
            var params = $.extend(defauts, options);

            var key = params.key;
            var $this = $(this);

            if (params.init === true)
            {
                var savedScroll = sessionStorage.getItem(key);

                if (typeof savedScroll != 'undefined')
                {
                    var int_savedScroll = parseInt(savedScroll);
                    if (int_savedScroll > 0)
                        $this.scrollTop(int_savedScroll);

                    setTimeout(function ()
                    {
                        var selectorFocus = sessionStorage.getItem(key + "-focus");
                        if (selectorFocus && selectorFocus != "")
                            $(document.querySelector(selectorFocus)).focus();
                    }, 100, key);
                }
            }

            window.addEventListener("beforeunload", function () 
            {
                sessionStorage.setItem(key, $this.scrollTop());
                if (document.activeElement)
                {
                    var selectorFocus = elemToSelector(document.activeElement);

                    if (selectorFocus)
                        sessionStorage.setItem(key + "-focus", selectorFocus);
                    else
                        sessionStorage.setItem(key + "-focus", "");
                }
                else
                    sessionStorage.setItem(key + "-focus", "");

            });
        };


    function elemToSelector(elem)   /* written by Kévin Berthommier */
    {
        const {
            tagName,
            id,
            className,
            parentNode
        } = elem;

        if (tagName === 'HTML') return 'HTML';

        let str = tagName;

        str += (id !== '') ? `#${id}` : '';

        if (className)
        {
            const classes = className.split(/\s/);
            for (let i = 0; i < classes.length; i++)
            {
                if(typeof classes[i] === 'string' && classes[i].length > 0)
                    str += `.${classes[i]}`;
            }
        }

        let childIndex = 1;

        for (let e = elem; e.previousElementSibling; e = e.previousElementSibling)
        {
            childIndex += 1;
        }

        str += `:nth-child(${childIndex})`;

        return `${elemToSelector(parentNode)} > ${str}`;
    }

})(jQuery);

/* 用法:

$('#tab1div').scrollKeeper({ key: 'uniq-key1', init: true });

如果您不需要恢复滚动位置(例如重新启动),而您只需要保存滚动位置以供下次使用,请使用:

$('#tab1div').scrollKeeper({ key: 'uniq-key1', init: false }); */