【问题标题】:Take User Back to Where They Scrolled to on previous page when clicking Browser Back Button单击浏览器后退按钮时,将用户返回到他们在上一页滚动到的位置
【发布时间】:2014-09-29 21:19:59
【问题描述】:

在浏览器中按下后退按钮时,是否可以将用户带回到他们向下滚动到的页面区域?如 --- pageA 是屏幕大小的两倍(因此您必须滚动才能阅读更多内容)。您单击 pageA 上的链接以转到新页面 - pageB。阅读后,您在浏览器中单击返回。现在,当您返回 pageA 时,您又回到了顶部,必须向下滚动到您要继续阅读页面其余部分的位置。

是否有 Jquery 或 JS 方式返回到页面中的那个点。也许有 .scrollTop() 的东西?

【问题讨论】:

  • 在 Firefox 中,我向下滚动一个页面,单击一个链接,阅读该页面,向下滚动,单击返回按钮,这是我离开滚动的地方,所以我不必向下滚动,它我离开的地方。你用的是什么浏览器?
  • 我在 Safari 中得到了相同的行为。
  • 我也在使用 FireFox。嗯 - 我只是注意到它只在我正在做的页面上产生这种效果。不是其他人。将不得不寻找原因。 PageA 主要是一个图片库(isotope.js)。也许它与画廊的加载有关。了解更多信息后会更新。
  • 是的,Chrome 会执行相同的操作(将您带回原位),但如果用户在页面完成加载之前滚动,或者 pageA 由于动态加载的内容而较长,则例外。
  • 这发生在我身上,但我意识到这是因为我在页面顶部的输入元素上设置了autofocus="true"。所以浏览器实际上是把我带回正确的位置,然后跳到顶部。删除它就可以了(并且可能只是动态地做)。

标签: javascript jquery browser back-button


【解决方案1】:

这绝对应该使用History API 来完成,因为它是确定用户使用浏览器的后退按钮返回页面的唯一方法。

首先,您要防止浏览器默认滚动恢复,以便自己处理。详情请见this article

if ('scrollRestoration' in history) history.scrollRestoration = 'manual'

然后你需要在用户离开页面时将滚动位置存储在history.state中。这可以使用history.replaceStatebeforeunload 上完成。

window.addEventListener('beforeunload', storeScrollPositionInHistoryState)
function storeScrollPositionInHistoryState() {
  // Make sure to add lastScrollPosition to the current state
  // to avoid removing other properties
  const newState = { ...history.state, lastScrollPosition: scrollY }

  // Pass the current location.href since you only want to update
  // the state, not the url
  history.replaceState(newState, '', location.href)
}

或使用 ES5

function storeScrollPositionInHistoryState() {
  var newState = Object.assign({}, history.state, { lastScrollPosition: scrollY })
  history.replaceState(newState, '', location.href)
}

最后,每当您的页面准备好滚动回其先前位置时,您检查是否定义了history.state.lastScrollPosition,如果是,则恢复滚动位置并将其从history.state 中删除。

function restoreLastScrollPositionIfAny() {
  if (typeof history.state.lastScrollPosition !== 'number') return

  scrollTo(scrollX, history.state.lastScrollPosition)
  const cleanState = { ...history.state }
  delete cleanState.lastScrollPosition
  history.replaceState(cleanState, '', location.href)
}

还有一个边缘情况没有被覆盖:

  • 用户可能在离开页面后调整了窗口大小,这可能导致返回页面时滚动位置不正确。开发人员经常调整窗口大小,但真正的用户并没有那么多。这就是我将其视为边缘案例的原因。

解决此问题的一种方法是将窗口大小也存储在history.state 中,如果当前窗口大小与状态中存储的不匹配,则避免恢复滚动位置。

希望对你有帮助。

【讨论】:

  • 很高兴知道哪些应该通过window访问
  • historyscrollToscrollXscrollYlocation 是您可以通过 window 访问的那些,但您不必这样做。
  • 这是很好的信息,而且比将状态存储在 cookie 或本地存储中要优雅得多。
【解决方案2】:
  //For Angular
  //Save your scroll position once you scroll
  @HostListener('window:scroll', ['$event']) onScrollEvent($event){
    sessionStorage.scrollPos = window.scrollY
  } 

  //Scroll to the save value postion
  ngAfterViewInit(){
    window.scrollTo(0, sessionStorage.scrollPos)
  }

【讨论】:

  • 欢迎来到 Stack Overflow。在 Stack Overflow 上不鼓励仅使用代码的答案,因为它们没有解释它是如何解决问题的。请编辑您的答案以解释此代码的作用以及它如何改进该问题已有的现有投票答案,以便对有类似问题的用户有用。
【解决方案3】:

在尝试@bowen 选项后,我已经找到了一个更好的选项,滚动流畅,没有@Frits 所说的问题

      $(window).scroll(function () {
        //set scroll position in session storage
        if ($(window).scrollTop() > 500)
          sessionStorage.scrollPos = $(window).scrollTop();
      });

      var init = setTimeout(function(){
         //return scroll position in session storage
         if (sessionStorage.scrollPos > 500){
            $("html").animate({ scrollTop: sessionStorage.scrollPos },2000);
          }
        },1000);
      window.onload = init;

【讨论】:

    【解决方案4】:

    您可以通过使用会话存储来做到这一点。

    $(window).scroll(function () {
      //set scroll position in session storage
      sessionStorage.scrollPos = $(window).scrollTop();
    });
    var init = function () {
       //return scroll position in session storage
       $(window).scrollTop(sessionStorage.scrollPos || 0)
    };
    window.onload = init;
    

    【讨论】:

    • 唯一的问题是,无论您在哪个页面上,它都会保存您的滚动位置。因此,如果在页面 A 上向下滚动 500 像素,然后单击链接以转到页面 B,它会将页面 B 向下滚动 500 像素。如果您查看this answer,您会注意到当前页面路径也存储在 sessionStorage 中,以确保目标页面正确。
    【解决方案5】:

    您可以使用以下代码来检测滚动位置。

     $(window).scroll(function (event){
        var scroll = $(window).scrollTop();
        // Do something
     });
    

    然后将滚动存储在会话中,当您单击返回时执行 scrollTop(scroll)

    【讨论】:

      【解决方案6】:

      如果内容是在页面“加载”事件触发后加载的,那么后退按钮不会带您回到原来的位置。因为浏览器在 'load' 事件之前滚动。

      在这种情况下,为了让浏览器记住滚动位置,您必须在导航离开之前将滚动位置和状态(已加载的内容)存储在某处。要么在 cookie 中,要么在 url 哈希中。

      如果pageA只是一个没有动态内容的静态页面(在'load'事件之后加载,当你返回时浏览器应该记住滚动位置。

      对于动态内容,至少包括两个部分。一种是单击“返回”按钮时恢复页面状态,因此加载了所有动态内容,一些扩展器被展开或折叠。另一个是滚动到那里。

      第一部分取决于页面是如何实现的。第二部分您可以在页面执行 onUnload 时将滚动顶部放入 cookie。例如

      $(window).unload(function() {$.cookie('scrollTop',$(window).scrollTop());});
      

      【讨论】:

      • 这正是正在发生的事情。如何将位置存储在 URL 哈希或 cookie 中?
      • 有没有办法在浏览器原生的后退按钮上设置事件监听器?
      猜你喜欢
      • 2017-10-07
      • 2021-09-29
      • 1970-01-01
      • 2022-11-22
      • 1970-01-01
      • 2017-05-23
      • 1970-01-01
      • 2021-01-16
      • 1970-01-01
      相关资源
      最近更新 更多