ajax|标准|程序|浏览器使用碎片标识符,我们可以创建一个“Ajax-URI”,其中的客户端部分和服务器端部分使用“#”隔开。
JavaScript提供了window.location()函数,以便通过URI更新浏览器的历史记录和地址。此外,我们可以使用window.location.hash()直接访问碎片标识符。
在下面的代码片断中,您可以看到如何通过对选择框使用onchange事件处理程序来扩展我们的代码,该处理程序使用一个“Ajax-URI”来更新浏览器历史记录及地址栏。
<html> <head> <script language="JavaScript" type="text/JavaScript"> function makeHistory(newHash) { window.location.hash = newHash; } function reportOptionValue() { var myForm = document.make_history; var mySelect = myForm.change_year; return mySelect.options[mySelect.selectedIndex].value; } function setOptionValue(value) { var myForm = document.make_history; var mySelect = myForm.change_year; mySelect.options[value-1].selected = true; } </script> </head> <body> <form name=make_history> <select name=change_year onchange= "return makeHistory(reportOptionValue())"> <option value="year_1">Year 1</option> <option value="year_2">Year 2</option> </select> </form> </body> </html>正如我们在图2中所看到的,选择框的每一次变动都将导致浏览器地址的更新。请注意,在需要使用隐藏帧以获取正确的行为的Internet Explorer (IE)中会存在一些问题,详细情况还是请参见Mike Stenhouse和Brad Neuberg的文章。
图2.状态变化时历史记录堆栈被更新
我们现在有了一个在选择框的值发生变化时创建新URI的事件处理程序。新URI使用碎片标识符存储重新创建先前状态所需的信息。现在我们可以着手实现下一个功能了。
- 恢复历史记录
- 检测URI的更改
- 通过URI重新创建状态
在第一步中,我们通过window.location.hash()函数更新了客户端的URI。这个调用并不会产生服务器的往返,也不会导致页面刷新。因此,我们需要使用Ajax的方法(在客户端)处理URI的改变。
首先需要增加一个轮询函数,以定时检查浏览器历史记录中的URI。我将在页面的onload事件中使用pollHash()函数,每隔1000毫秒它将重新执行一次。
这个轮询函数将调用handleHistory()函数,后者检查在上一次检查之后URI是否改变了。我们将借助一个名为expectedHash的全局变量来实现。
最后一部分是确定URI是否发生了改变,这种改变由选择框中的事件处理程序引起,或者是因为终端用户单击了后退按钮而造成。我们通过在选择框的事件处理程序中设置expectedHash来达到此目的。
<html> <head> <script language="JavaScript" type="text/JavaScript"> var expectedHash = ""; function makeHistory(newHash) { window.location.hash = newHash; expectedHash = window.location.hash; return true; } function reportOptionValue() { var myForm = document.make_history; var mySelect = myForm.change_year; return mySelect.options[mySelect.selectedIndex].value; } function setOptionValue(value) { var myForm = document.make_history; var mySelect = myForm.change_year; mySelect.options[value-1].selected = true; return true; } function handleHistory() { if ( window.location.hash != expectedHash ) { expectedHash = window.location.hash; var newoption = expectedHash.substring(6); setOptionValue( newoption ); } return true; } function pollHash() { handleHistory(); window.setInterval("handleHistory()", 1000); return true; } </script> </head> <body language="JavaScript" > <form name=make_history> <select name=change_year > <option value="year_1">Year 1</option> <option value="year_2">Year 2</option> </select> </form> </body> </html>到此,我们的示例程序就完成了。在这个程序中,我们演示了如何在URI中记录状态,如何将URI添加到浏览器的历史记录堆栈中,如何从后退按钮检测地址变动,以及最终如何重新创建所需的状态。
这个示例程序还缺少以下功能:
- 对使用隐藏帧的IE的支持
- 更多的固定URI(这个示例程序只用于选择框选项少于10的情况)
- 在构造时注册初始状态
以一种兼容所有浏览器的健壮方式实现对所有传统的Web可用功能的处理不是一件容易的事。一种替代方法是使用对这些功能提供了内置支持的Ajax工具包。