Tag Archives: html5

Hello World 他山石

3D立方体

只支持safari和chrome ;)

1
2
3
4
5
6
7
8
9
10
11
12


转自:http://www.webkit.org/blog-files/3d-transforms/morphing-cubes.html

Hello World 业界杂谈

整站ajax中url的处理

早在两年前,互联网中的网页数量就已超过了1万亿,并且,每天还会增加数十亿。虽然是如此浩瀚的世界,我们却可以通过url轻而易举的找到每一个页面,可见url对于网络世界时多么的重要。

随着浏览器的进步和对用户体验要求的提升,整站ajax之类的一站式前端应用正在逐步取代传统的一个url对一个页面的展示方式。在整站ajax中,数个模块在一个url下,采用无刷新的方式切换,通过减少页面刷新有效的提升了用户体验,但也带来了一些问题:

1. 某些用户习惯根据url判断自己所在的位置,如果明明点击了链接,页面变化了,url却没有变化,用户会比较晕

2. 用户保存书签后,在打开这个书签,得到的可能并不是自己想要的内容

3. 模块间切换后,不能使用浏览器的回退键退回去

针对上述问题,比较简单的方式是使用锚点做标记:每个模块切换时,锚点都会有所变化,比如:/index#list,/index#edit,这样,可以有效的解决上面提到的第1个问题;对第2个问题,前端代码初始化时根据当前页面的hash做些处理也就行了;第3个问题稍微麻烦一些,需要监控页面url的变化。

浏览器不可以给地址栏添加监听时间,只能通过定时读取location.hash/href来判断锚点是否发生了变化。定时长度不能太长,否则影响用户体验,也不能太频,会耗太多资源。这种定时的方式虽然很土,但出了“坚挺”浏览器是否回退、前进以外,却还可以减少很多绑定链接click的操作:只需要给按钮链接的href加上锚点,将参数写在锚点里,用户点击这个url时,锚点变化被定时程序“监听”到,就可以执行相应的逻辑(还顺道解决了按钮重复点击的问题,一举多得呀 :-) )。关于如何把button按钮转变为锚点链接的点击可以参考本人以前的博文:js触发链接

不过使用定时方式“监听”浏览器回退,还有一个无法解决的缺陷(只是本人还未发现解决方法),IE6/7的锚点跳转记录不会进入history对象,也就是在IE6/7里,有A页面进入B页面后,B页面内由/B跳到/B#1,再跳到/B#2,再“回退”,也还是会回到A页面,无法回到中间的/B跳和/B#1…….IE而已,可以暂时不去理它。

前面说,使用方式监听地址栏变化有些土,那么,有跟好的办法吗?

之前转发的一篇博文(使用ajax和history.pushState无刷新改变页面URL)里提到了html5的一个新特性:可以注册“popstate”事件监听url的变化,我们可把前面的定时“监听”稍作改进,如果浏览器支持popstate,就使用popstate,如果不支持,在使用定时。本人测试表明,firefox、chrome、safari支持popstate事件,IE系、以及opera不支持。

———-End

Hello World 他山石

[转]使用ajax和history.pushState无刷新改变页面URL

在访问现在很火的google plus时,细心的用户也许会发现页面之间的点击是通过ajax异步请求的,同时页面的URL发生了了改变。并且能够很好的支持浏览器的前进和后退。不禁让人想问,是什么有这么强大的功能呢?

HTML5里引用了新的API,就是history.pushState和history.replaceState,就是通过这个接口做到无刷新改变页面URL的。

与传统的AJAX的区别

传统的ajax有如下的问题:

虽然ajax可以无刷新改变页面内容,但无法改变页面URL

其次为了更好的可访问性,内容发生改变后,改变URL的hash。但是hash的方式不能很好的处理浏览器的前进、后退等问题

有的浏览器引入了onhashchange的接口,不支持的浏览器只能定时去判断hash是否改变

再有,ajax的使用对搜索引擎很不友好,往往蜘蛛爬到的区域是空的

为了解决传统ajax带来的问题,HTML5里引入了新的API,即:history.pushState, history.replaceState

可以通过pushState和replaceState接口操作浏览器历史,并且改变当前页面的URL。

pushState是将指定的URL添加到浏览器历史里,replaceState是将指定的URL替换当前的URL。

如何调用

var state = {
	title: title,
	url: options.url,
	otherkey: othervalue
};
window.history.pushState(state, document.title, url);

state对象除了要title和url之外,也可以添加其他的数据,比如:还想将一些发送ajax的配置给保存起来。

replaceState和pushState是相似的,不需要多做解释。

如何响应浏览器的前进、后退操作

window对象上提供了onpopstate事件,上面传递的state对象会成为event的子对象,这样就可以拿到存储的title和URL了。

window.addEventListener('popstate', function(e){
  if (history.state){
	var state = e.state;
    //do something(state.url, state.title);
  }
}, false);

这样就可以结合ajax和pushState完美的进行无刷新浏览了。

一些限制

1、无法跨域,这个是必然的。引用曾经在网上看到的一句经典的话:“如果javascript可以跨域的话,那他就可以逆天了!”

2、state对象虽然可以存储很多自定义的属性,但值不能是个对象。

对应后端的一些处理

这种模式下除了当前使用ajax可以无刷新浏览外,还要保证直接请求改变的URL后也可以正常浏览,所以后端要对这些处理下。

1、对结合pushState的ajax可以发送一个特殊的头,如: setRequestHeader(‘PJAX’, ‘true’)。

2、后端获取到有PJAX=true的header时,将页面中通用的部分都不输出。比如:PHP可以通过下面的判断

function is_pjax(){
	return array_key_exists('HTTP_X_PJAX', $_SERVER) && $_SERVER['HTTP_X_PJAX'] === 'true';
}

虽然接口上只有pushState、replaceState、onpopstate,但在使用的时候还是要做很多处理的。
————–
转自:http://www.52ladybug.com/?p=202