页面返回保留上一页信息解决方案

  • 约188字
  • 技术
  • 2015年2月15日

当用户在网页中点击链接进入下一页,再点击返回按钮,希望重新展示上一页的内容,并且停留在上次离开的地方。这对于传统的服务器端网页技术(利用 php,jsp 生成好 html 然后整体返回给浏览器)没有任何问题。随着前端技术的不断升级换代,dom 越来越多是在前端用 javascript 生成,这时返回按钮通常会导致上一个页面的 dom 重新生成一遍,之前的数据和页面内容都会丢失。

页面 URL 发生变化分两类:

  1. 不发起新 http 请求(应用内跳转):只改变 URL 的 hash 部分或者用 html5 的 history.pushState,此时 URL 虽然变化,但是不会重新发起新的 http 请求。
  2. 请求了一个新的页面(应用外跳转):在网页中点击链接,或者 location.href 改变都会发起新的 http 请求。

针对上面两类跳转,对应的返回也分两类,解决方法也略有不同。但基本思路是一样的,就是在发生上述两类跳转时,将当前页面的 state 信息保存到 sessionStorage。当页面返回时,直接从 sesseionStorage 读出 state 信息生成页面。

接下来的问题是如果判断用户是从返回按钮回来的,如果用户不是通过返回按钮来到页面,则先清除相关的 sessionStorage,保证页面数据会重新获取。通过在 html 中设置一个隐藏的 form,里面 is_from_back 默认位 0,当页面跳转时设定其值为 1。就可以通过 is_from_back 的值来判断是否来自于后退按钮了。

关键代码实例:(使用 angular 和 ui-route)

html

<form name="ignore_me">
  <input type="hidden" id="is_from_back" value="0" />
</form>

angular stateCache service

servicesModule.factory("stateCache", function ($state) {
  function initApp() {
    // 应用内返回: 不会调用本方法
    // 应用外返回: 不 clear 数据
    if (document.getElementById("is_from_back").value === "0") {
      // 不是来自返回按钮
      storage.clear();
    }
  }

  function initCtrl($scope, keys, fn) {
    var stateName = $state.$current.name;
    var state = get(stateName);

    if (state && state.keys === keys.join(",")) {
      keys.forEach(function (key) {
        $scope[key] = state.data[key];
      });
    } else {
      fn();
    }

    var onLocationChange = function () {
      var data = {};
      keys.forEach(function (key) {
        data[key] = $scope[key];
      });

      var state = {
        keys: keys.join(","),
        data: data,
      };
      set(stateName, state);
      document.getElementById("is_from_back").value = "1";
    };
    window.onbeforeunload = onLocationChange;
    $scope.$on("$stateChangeStart", onLocationChange);
  }

  return {
    initApp: initApp,
    initCtrl: initCtrl,
  };
});

use the service in angular

angular.run(function () {
  stateCache.initApp();
});

function Controller($scope, stateCache) {
  stateCache.initCtrl($scope, keys, initFn);
}

相关文章

如何更高效的完成 API 联调

在日常开发工作中,离不开各种联调工作,包括 Web 前后端联调、后端服务之间的联调。API 是应用程序之间沟通的桥梁,联调则是 API 提供者和 API 使用者一起完成这座桥梁安装和调试的过程。

查看更多

成长在凤金 (北邮校招分享)

前晚(周五)作为校友参加凤凰金融在北邮的校招宣讲会,做了一个小分享,主要讲在公司一年半以来的成长,下面是分享的内容。

查看更多

用 poetry 做 python 项目依赖管理

Poetry 是一个用于 Python 项目的依赖管理和打包工具,旨在简化和改善 Python 包的创建和管理过程。本文通过对比 Node.js 的 yarn 工具,介绍了 python 的依赖包管理工具 Poetry 的安装以及基本使用方法。

查看更多