你的位置:首页 > 网页设计

[网页设计]HTML5中的History和Location对象


今天发现原来HTML5对History和Location对象进行了改进,提供了几个新的API。我觉得,这用来结合Ajax来使用,弥补Ajax技术更新内容但不产生历史记录的问题,十分有用。

我很久之前就想过通过锚点来解决实现书签和定位,配合iframe使用一些小技巧,还可以实现历史记录的产生。后来发现,原来IE8和其它现代浏览器都大都已经实现了更改锚点来产生历史记录了

记得,我第一次做的一个相关的小应用是工大在线的翻页书签功能:http://www.gdutonline.com/newstudent/Detail.aspx?id=14814,这个页面的分页是在前端负责的,所以如果不加处理,去到任何一页码都是同一个URL。我的处理方法是:用户点击翻页的时候,锚点会改变,如果把带锚点的网址发给别人,他也会去到该页。但是,我没有做历史记录的实现,就是说,但用户从第一页到第二页,再点击返回的时候,页面不会跳转到第一页,因为浏览器只负责改变URL,这些更改后的URL需要怎么解析要我们自己写程序。但问题是,我们如何知道用户点击前进后退了?就是URL改变了?这需要我们手动来实现,一般有三种方法:

  1. 使用定时器来侦听URL变化以触发事件,这个方法兼容性好,被很多框架所采用,但是长期反复检查URL,效率很低。我在Web文件管理系统中就是采用了这套方案。但是在IE6,7中,只见诶需要解决不产生历史记录的问题,一般可以通过嵌入iframe解决。
  2. 使用插入iframe等一系列旁门左道,下面的参考资料可以看,这些方法可能不太成熟,不宜用在真正项目中。
  3. 使用HTML5的onhashchange事件,这个太鸡冻人心了,正是我们要的。但是,它的缺点是需要支持HTML5的浏览器支持。

下面开始讨论一下HTML5中的History和Location新特性,主要就是两个方法和两个事件。

window . history . pushState(data, title [, url ] )
在历史记录中插入一个新的记录,第一个参数表示要传递的数据,在下面介绍的事件中可以用到,title用来描述这个页面的,最后一个可选参数是用来更改URL的,这个我觉得很神奇,因为在方法执行后,URL更改了(不仅仅是锚记和查询字符串),但是页面还是原来的那个。当这个方法执行之后,历史记录里面会插入一个新的记录。

window . history . replaceState(data, title [, url ] )
这个方法和上面的差不多,只是上面的是插入新纪录,而这个是更新本记录。不再冗述。

PopStateEvent 事件

这个事件是在历史位置改变的时候触发的,主要有两种情况,一个是我们在代码中使用pushState和replaceState插入新的历史记录时候会触发,另外一种是我们点击前进后退或者选择某个历史位置的时候触发。每个历史位置都有一个data数据,就是pushState和replaceState的第一个参数,我们可以通过事件参数中的state属性来获取该历史记录中的data参数。

HashChangeEvent事件

这个事件是当锚记改变的时候触发的,触发这个事件的方法就有很多种了:1.直接代码修改location.hash;2.网页中的超链接跳转;3使用上述两个History方法修改URL锚记。这些方法都可以触发HashChangeEvent事件。并且,事件参数中有两个属性:oldURL和newURL可以获取。

纵观这几个新特性,我们可以看到HTML5对于网页的历史模型进行了大大的改进,特别在使用Ajax应用的时候,前进后退书签这些都可以回复它们本来的角色了。细观上面两个事件,可能有人会觉得功能有些重复了:如果单独使用PopStateEvent和PopState,可以通过data传送数据,使用历史记录来定位,但是因为位置没有在URL中反映出来,不能实现书签功能;而使用HashChangeEvent和锚记的话,可以实现书签功能,并且可以很好地配合上超链接标签使用,但是这也有一个缺点,因为唯一标识是记录在锚记上,这意味着不能存储大量页面数据。最完美的方法是,它们全部一齐配合着使用,PushState方法和PopStateEvent主要负责庞大的页面数据储存和传递,HashChangeEvent负责页面URL标识和书签功能,完美啦~

剩下的还是老问题……浏览器们什么时候可以都给支持一下啊?……