编写类
我们来看看历史堆栈中需要存储的数据或属性。前面已经讨论了堆栈(数组)和指针。stack_limit 属性可以防止因为数据过多而造成的 cookie 溢出(参见清单 1)。在实践中,我们希望在删除最老的记录之前能够存储 40-50 个事件。出于测试的目的,我们将该值设置为 15。
清单 1. 历史堆栈的构造,包括类的属性
function HistoryStack () { this.stack = new Array(); this.current = -1; this.stack_limit = 15; } |
除了这三个属性外,该类还需要一些方法来添加元素、检索堆栈数据以及将堆栈数据保存到浏览器 cookie 中。首先看一看 addResource() 方法,它用于将记录压入历史堆栈的堆栈顶部(参见清单 2)。注意,如果堆栈的长度超过了 stack_limit,那么最老的记录将从堆栈中移走。
清单 2. addResource() 方法,向历史堆栈的堆栈顶部添加记录
HistoryStack.prototype.addResource = function(resource) { if (this.stack.length > 0) { this.stack = this.stack.slice(0, this.current + 1); } this.stack.push(resource); while (this.stack.length > this.stack_limit) { this.stack.shift(); } this.current = this.stack.length - 1; this.save(); }; |
给历史堆栈添加的以下三个方法用于从该类中获取信息(参见清单 3)。getCurrent() 返回堆栈指针指向的当前记录,这在堆栈中导航的时候非常有用。hasPrev() 和 hasNext() 方法返回 Boolean 值,告诉我们当前记录之前或之后是否还有记录,或者指示我们到达了堆栈顶部或堆栈尾部。这些方法很简单,但是确定后退和前进按钮的状态时很有用。
清单 3. 历史堆栈定义的方法
HistoryStack.prototype.addResource = function(resource) HistoryStack.prototype.getCurrent = function () { return this.stack[this.current]; };
HistoryStack.prototype.hasPrev = function() { return (this.current > 0); };
HistoryStack.prototype.hasNext = function() { return (this.current < this.stack.length - 1 && this.current > -1); }; |
现在就可以向历史堆栈中添加记录并确定所在的位置了。但还是无法在堆栈中导航。清单 4 中定义的 go() 方法允许我们在堆栈中来回移动。通过传递正或负的增量就可以在堆栈中向前或向后移动。这与 JavaScript 内置的 location.go() 方法类似。既然模仿内置功能,为何不根据这些已有的方法建立模型呢?
此外,我们还可用该方法实现刷新功能。可以通过传递正或负的参数在堆栈中导航。传递零时则会刷新当前页面。
清单 4. 历史堆栈的 go() 方法
HistoryStack.prototype.go = function(increment) { // Go back... if (increment < 0) { this.current = Math.max(0, this.current + increment);
// Go forward... } else if (increment > 0) { this.current = Math.min(this.stack.length - 1,this.current + increment); // Reload... } else { location.reload(); } this.save(); }; |
到目前为止,只要 HistoryStack 对象存在于当前文档中,这个新建的类就能正常工作。我们已经讨论了刷新页面会造成数据丢失的问题,现在来解决它。清单 5 中添加了在浏览器 cookie 中设置和访问数据的方法。所要做的只是设置每个 cookie 的名称值对。因为只需要在浏览器会话中保存 cookie,而不需要设置有效期。为了简化示例,我们不考虑其他参数,如 secure、domain 和 path。
注意:如果该类需要对 cookie 做复杂处理,更明智的办法是使用完全独立的 cookie 管理类。建立和读取 cookie 有点偏离历史堆栈的正题。如果 JavaScript 允许指定方法和属性访问的作用域,也可以将这些方法设成私有的。
清单 5. 建立和访问浏览器 cookie 的方法
HistoryStack.prototype.setCookie = function(name, value) { var cookie_str = name + "=" + escape(value); document.cookie = cookie_str; };
HistoryStack.prototype.getCookie = function(name) { if (!name) return ''; var raw_cookies, tmp, i; var cookies = new Array(); raw_cookies = document.cookie.split('; '); for (i=0; i < raw_cookies.length; i++) { tmp = raw_cookies[i].split('='); cookies[tmp[0]] = unescape(tmp[1]); } if (cookies[name] != null) { return cookies[name]; } else { return ''; } }; |
定义了管理任何 cookie 的方法之后,可以编写另外两个类专门处理历史堆栈的类。save() 方法将堆栈转化成字符串并保存到 cookie 中,load() 重新将字符串解析成用于管理历史堆栈的数组(参见清单 6)。
清单 6. save() 和 load() 方法
HistoryStack.prototype.save = function() { this.setCookie('CHStack', this.stack.toString()); this.setCookie('CHCurrent', this.current); };
HistoryStack.prototype.load = function() { var tmp_stack = this.getCookie('CHStack'); if (tmp_stack != '') { this.stack = tmp_stack.split(','); }
var tmp_current = parseInt(this.getCookie('CHCurrent')); if (tmp_current >= -1) { this.current = tmp_current; } }; |
 
说明:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。
2/2 首页 上一页 1 2 |