之前在冰雪林博客上看到有个历史浏览记录的功能,问了下他是用 localStorage 实现的。
于是,自己网上找了找实例,自己改了改在 typecho 上实现了该功能。
本来也打算做个单页来展示历史文章,奈何菜单栏上已经很多了,哈哈。
其实这个功能一定程度上可以挽留一下读者,比如:某位大佬经常通过搜索引擎进来我站,可能发现以前在这里也看过一些文章,比较合他口味,久而久之就能发展成常客啦。
实现原理:这个功能实现非常简单,实现方法也很多,比如可以将内容保存在 cookie 中,但用 cookie 储存存在一些问题。cookie 是 HTTP 响应一起被发送的, 会对服务器端响应时间产生一定程度的影响。
不过用 cookie 是最实用的,因为几乎可以兼容所有浏览器。我这里使用的 localStorage,数据完全保存在浏览器中,不会有影响服务器响应, 但是在 IE 中不能使用!
实现步骤:首先在网站中引入 viewhistory.js,下面就是全部脚本代码:
ViewHistory = function() {
this.config = {
limit: 10,
storageKey: 'viewHistory',
primaryKey: 'url'
};
this.cache = {
localStorage: null,
userData: null,
attr: null
};
};
ViewHistory.prototype = {
init: function(config) {
this.config = config || this.config;
var _self = this;
if (!window.localStorage && (this.cache.userData = document.body) && this.cache.userData.addBehavior && this.cache.userData.addBehavior('#default#userdata')) {
this.cache.userData.load((this.cache.attr = 'localStorage'));
this.cache.localStorage = {
'getItem': function(key) {
return _self.cache.userData.getAttribute(key);
},
'setItem': function(key, value) {
_self.cache.userData.setAttribute(key, value);
_self.cache.userData.save(_self.cache.attr);
}
};
} else {
this.cache.localStorage = window.localStorage;
}
},
addHistory: function(item) {
var items = this.getHistories();
for(var i=0, len=items.length; i<len; i++) {
if(item[this.config.primaryKey] && items[i][this.config.primaryKey] && item[this.config.primaryKey] === items[i][this.config.primaryKey]) {
items.splice(i, 1);
break;
}
}
items.push(item);
if(this.config.limit > 0 && items.length > this.config.limit) {
items.splice(0, 1);
}
var json = JSON.stringify(items);
this.cache.localStorage.setItem(this.config.storageKey, json);
},
getHistories: function() {
var history = this.cache.localStorage.getItem(this.config.storageKey);
if(history) {
return JSON.parse(history);
}
return [];
}
};
function jl_viewHistory(config){
if(typeof localStorage !== 'undefined' && typeof JSON !== 'undefined') {
var viewHistory = new ViewHistory();
viewHistory.init({
limit: config.limit,
storageKey: config.storageKey,
primaryKey: config.primaryKey
});
}
// 如果
var wrap = document.getElementById(config.storageKey);
if(!viewHistory){
if(wrap){
wrap.style.display = 'none';
}
return;
}
// 如果 ViewHistory 的实例存在,并且外层节点存在,则可显示历史浏览记录
if(viewHistory && wrap) {
// 获取浏览记录
var histories = viewHistory.getHistories();
// 组装列表
var list = document.createElement('ul');
if(histories && histories.length > 0) {
for(var i=histories.length-1; i>=0; i--) {
var history = histories[i];
var item = document.createElement('li');
var link = document.createElement('a');
link.href = history.url;
link.innerHTML = history.title;
item.appendChild(link);
list.appendChild(item);
}
// 插入页面特定位置
wrap.appendChild(list);
}
}
if( viewHistory && config.addHistory) {
var page = {
"title": document.getElementsByTagName('title')[0].innerHTML.split(config.titleSplit)[0],
// 这里需要注意把标题的 class 名替换掉
"url": location.href // 这是 primaryKey
// "time": ...
// "author": ...
// 这里可以写入更多相关内容作为浏览记录中的信息
};
viewHistory.addHistory(page);
}
}
显示组件:在需要添加显示历史记录的地方添加:
<div id="jl_viewHistory" >
<h3>您刚刚看过如下文章:</h3>
</div>
这里注意:id 属性的值可以随便取,但是后面要用到。
调用脚本方法:在网站 footer 文件中添加以下调用代码:
<script>
jl_viewHistory({
limit: 5,
storageKey: 'jl_viewHistory',
primaryKey: 'url',
addHistory: true;
titleSplit: '|'
});
</script>
limit 用于记录显示的条数和存储的条数,可自行修改条数
storyageKey 用于配置需要显示的 id,也代表着 localStorage 保存这些历史记录的为一个值
primaryKey 用户表示存储字段中以什么字段作为数据唯一的判断(一般以 url)
addHistory 是否添加历史记录,一般主页不需要保存,而文章页需要保存
如果你用的是 typecho 那可以用下面逻辑判断:
addHistory: <?php if ($this->is('post')) { ?> true <?php }else{ ?>false<?php } ?>
titleSplit 用于表示标题以什么作为切割,切割之后取第一截。
最后是效果:
再次强调下,该功能在 Ie 下可能无法显示,不过也不影响效果。
因为是自己折腾的,不能保证所有网站可用哈,有啥问题也可以提出来。
由于之前站内的内容全清空了,无意间在别人的博客里看到了之前自己写的这篇文章,作者也在最后加上了我的原文链接,哈哈,自己再把以前写的内容搬回来记录下。