用 localStorage 实现浏览记录,访问过的历史文章

用户在历史浏览记录中可以看到最近他在这个网站看过的几个文章。

1.jpg

是用 localStorage 实现的,网上找了找实例,自己改了改在 typecho 上实现了该功能。

本来是打算做个单页来展示历史文章,奈何菜单栏上已经很多了,哈哈,最后暂时加在了文章底部,美化样式什么的暂时还没有太好的想法,先这样吧。

2.jpg

其实这个功能一定程度上可以挽留一下读者,比如:某位大佬经常通过搜索引擎进来我站,可能发现以前在这里也看过一些文章,比较合他口味,久而久之就能发展成常客啦。

实现原理

这个功能实现非常简单,实现方法也很多,比如可以将内容保存在 cookie 中,但用 cookie 储存存在一些问题。cookie 是随 HTTP 响应一起被发送的, 会对服务器端响应时间产生一定程度的影响。

其实利用 cookie 是最实用的,因为几乎可以兼容所有浏览器。我这里使用的 localStorage,数据完全保存在浏览器中,不会有影响服务器响应, 但是在 IE6/7 中不能使用!

实现步骤

首先在网站中引入 viewhistory.js,下面就是全部脚本代码:

  1. ViewHistory = function() {
  2. this.config = {
  3. limit: 10,
  4. storageKey: 'viewHistory',
  5. primaryKey: 'url'
  6. };
  7. this.cache = {
  8. localStorage: null,
  9. userData: null,
  10. attr: null
  11. };
  12. };
  13. ViewHistory.prototype = {
  14. init: function(config) {
  15. this.config = config || this.config;
  16. var _self = this;
  17. if (!window.localStorage && (this.cache.userData = document.body) && this.cache.userData.addBehavior && this.cache.userData.addBehavior('#default#userdata')) {
  18. this.cache.userData.load((this.cache.attr = 'localStorage'));
  19. this.cache.localStorage = {
  20. 'getItem': function(key) {
  21. return _self.cache.userData.getAttribute(key);
  22. },
  23. 'setItem': function(key, value) {
  24. _self.cache.userData.setAttribute(key, value);
  25. _self.cache.userData.save(_self.cache.attr);
  26. }
  27. };
  28. } else {
  29. this.cache.localStorage = window.localStorage;
  30. }
  31. },
  32. addHistory: function(item) {
  33. var items = this.getHistories();
  34. for(var i=0, len=items.length; i<len; i++) {
  35. if(item[this.config.primaryKey] && items[i][this.config.primaryKey] && item[this.config.primaryKey] === items[i][this.config.primaryKey]) {
  36. items.splice(i, 1);
  37. break;
  38. }
  39. }
  40. items.push(item);
  41. if(this.config.limit > 0 && items.length > this.config.limit) {
  42. items.splice(0, 1);
  43. }
  44. var json = JSON.stringify(items);
  45. this.cache.localStorage.setItem(this.config.storageKey, json);
  46. },
  47. getHistories: function() {
  48. var history = this.cache.localStorage.getItem(this.config.storageKey);
  49. if(history) {
  50. return JSON.parse(history);
  51. }
  52. return [];
  53. }
  54. };
  55. function jl_viewHistory(config){
  56. if(typeof localStorage !== 'undefined' && typeof JSON !== 'undefined') {
  57. var viewHistory = new ViewHistory();
  58. viewHistory.init({
  59. limit: config.limit,
  60. storageKey: config.storageKey,
  61. primaryKey: config.primaryKey
  62. });
  63. }
  64. // 如果
  65. var wrap = document.getElementById(config.storageKey);
  66. if(!viewHistory){
  67. if(wrap){
  68. wrap.style.display = 'none';
  69. }
  70. return;
  71. }
  72. // 如果 ViewHistory 的实例存在,并且外层节点存在,则可显示历史浏览记录
  73. if(viewHistory && wrap) {
  74. // 获取浏览记录
  75. var histories = viewHistory.getHistories();
  76. // 组装列表
  77. var list = document.createElement('ul');
  78. if(histories && histories.length > 0) {
  79. for(var i=histories.length-1; i>=0; i--) {
  80. var history = histories[i];
  81. var item = document.createElement('li');
  82. var link = document.createElement('a');
  83. link.href = history.url;
  84. link.innerHTML = history.title;
  85. item.appendChild(link);
  86. list.appendChild(item);
  87. }
  88. // 插入页面特定位置
  89. wrap.appendChild(list);
  90. }
  91. }
  92. if( viewHistory && config.addHistory) {
  93. var page = {
  94. "title": document.getElementsByTagName('title')[0].innerHTML.split(config.titleSplit)[0],
  95. // 这里需要注意把标题的class名替换掉
  96. "url": location.href // 这是 primaryKey
  97. // "time": ...
  98. // "author": ...
  99. // 这里可以写入更多相关内容作为浏览记录中的信息
  100. };
  101. viewHistory.addHistory(page);
  102. }
  103. }

显示组件

在需要添加显示历史记录的地方添加:

  1. <div id="jl_viewHistory" >
  2. <h3>您刚刚看过如下文章:</h3>
  3. </div>

这里注意:id属性的值可以随便取,但是后面要用到。

调用脚本方法

在网站 footer 文件中添加以下调用代码:

  1. <script>
  2. jl_viewHistory({
  3. limit: 5,
  4. storageKey: 'jl_viewHistory',
  5. primaryKey: 'url',
  6. addHistory: true;
  7. titleSplit: '|'
  8. });
  9. </script>
  10. limit 用于记录显示的条数和存储的条数,可自行修改条数
  11. storyageKey 用于配置需要显示的id,也代表着localStorage保存这些历史记录的为一个值
  12. primaryKey 用户表示存储字段中以什么字段作为数据唯一的判断(一般以url)
  13. addHistory 是否添加历史记录,一般主页不需要保存,而文章页需要保存
  14. 如果你用的是 typecho 那可以用下面逻辑判断:
  15. addHistory: <?php if ($this->is('post')) { ?> true <?php }else{ ?>false<?php } ?>,
  16. titleSplit用于表示标题以什么作为切割,切割之后取第一截。

再次强调下,该功能在 Ie6,7 下无法显示,不过也不影响效果。

因为是自己折腾的,不能保证所有网站可用哈,有啥问题也可以提出来,我暂时使用没问题,后期再修改修改。

文章来源:https://www.jdeal.cn/archives/localStorage.html

文章由官网发布,如若转载,请注明出处:https://www.veimoz.com/288
2 条评论
5.5k

发表评论

已有 2 条评论

  1. GDX     Win 10 /    QQ浏览器
    2020-05-23 14:49

    按操作怎么用不了,没显示。

    1. 【管理员】Vv     Win 7 /    Chrome
      2020-05-23 15:48

      @GDX

      是可以的,我自己都试了,可能你没有配置对,先理解思路,再尝试操作……

!