最近在做博客个人中心feed分类,需求如下:(1)点击列表中的每一项显示相应的数据,如我点击喜欢,feed里相应展示喜欢的feed;点击博文,feed里展示博文的 feed。
(2)刷新当前页面,显示相应的内容。如我在看喜欢的feed,此时刷新页面,应该还是显示喜欢的feed。
(3)要支持浏览器的前进后退按钮。
开发过程:
此需求我最先想到的就是通过hash去操作,其中主要应用到的事件就是onhashchange事件,但是此事件标准浏览都支持,ie6,7下要通过iframe实现参考链接如下:http://www.oushit.com/?p=207(补充一下,自已研究好长时间了,到目前为止都是一头雾水,晕倒了)
。先上一 下自己写的demo1,demo2:在看demo之前:大家先看一下window.location对象:相关文档如下:
https://developer.mozilla.org/en-US/docs/DOM/window.location
关于hash用的时候最好编码在译码,因为火狐对hash的处理存在一个bug,其它的都正常
example :http://www.example.com/search?q=Fire%20fox#Fire%20fox
results in: firefox hash=#Fire fox ; chrome: hash=#Fire%20fox
其他的都正常: search=?q=Fire%20fox
(1)demo1主要应用onhashchange事件,chrome,fox,ie8都支持此事件
主要思路如下:当hash发生更改的时候,onhashchange事件就会触发(包括单击a标签,点击浏览器前进后退按钮),此方法并没有给a标签绑定事件,而是通过锚点去实现,hash一变更,就会触发onhashchange事件。使用此方法上面的 三个需求都可以完成,
但是ie6,7下需要重新编写代码来修补一下。我刚开始写的时候对ie6,7是通过轮询不断的监听hash是否变化,来实现单击a标签下面的div框显示相应的内容。但是却不能前进后退,让我很头大,这个待后续研究。
代码如下:
html代码:
<a href="#a" title="" id="a">11111</a>
<a href="#b" title="" id="b">22222</a>
<a href="#c" title="" id="c">33333</a>
<div id="diva">aaaaaaaaaaaaaaaaaaaaaa</div>
<div id="divb" style="display:none;">bbbbbbbbbbbbbbbbbbbbbb</div>
<div id="divc" style="display:none;">cccccccccccccccccccccc</div>
js代码:
var lastState;
lastState = window.location.hash.replace(/#/g,"");
stateChange(lastState); //此代码用来完成页面刷新的时候显示当前页的内容
// 对hash的监听
var hashchange = function(){
var newState = window.location.hash.replace(/#/g,"");
if(lastState != newState) {
stateChange(lastState = newState);
}
}
window.onhashchange = function(){
hashchange();
}
function stateChange(url){
switch(url){
case 'a':
document.getElementById("diva").style.display = "block";
document.getElementById("divb").style.display = "none";
document.getElementById("divc").style.display = "none";
break;
case 'b':
document.getElementById("divb").style.display = "block";
document.getElementById("diva").style.display = "none";
document.getElementById("divc").style.display = "none";
break;
case 'c':
document.getElementById("divc").style.display = "block";
document.getElementById("divb").style.display = "none";
document.getElementById("diva").style.display = "none";
break;
case "":
document.getElementById("diva").style.display = "block";
document.getElementById("divb").style.display = "none";
document.getElementById("divc").style.display = "none";
break;
}
};
(2)应用html5对history的新增特性pushstate方法和结合onpopstate事件来完成此浏览器的前进后退
2.1 此方法有三个参数,pushstate(state, title, url);第一个参数是event对象的一个属性(可以这么理解的),并且是历史记录state对象的一个副本(此方法 使用了结构话克隆算法扩展了此对象),第二个参数是链接地址的标题,一般情况下传入“”,为了向后兼容,第三个参数就是传入的链接地址,对于次 方法的详细解释可以参考:
https://developer.mozilla.org/en-US/docs/DOM/Manipulating_the_browser_history
注意:当调用此方法的时候,浏览器并不会企图去加载当前的url,(理解成ajax请求)
2.2 调用pushstate方法并不会触发popstate event,只有点击浏览器的前进后退按钮,才会触发此事件,此事件的详细信息请看:
https://developer.mozilla.org/en-US/docs/DOM/window.onpopstate
这个事件的 触发与onhashchange事件不同。但是使用此方法还是需要绑定事件:
代码如下:
html代码:
<a href="javascript:void(0);" title="" id="a">11111</a>
<a href="javascript:void(0);" title="" id="b">22222</a>
<a href="javascript:void(0);" title="" id="c">33333</a>
<a href="javascript:void(0);" title="" id="d">4444</a>
<div id="diva">aaaaaaaaaaaaaaaaaaaaaa</div>
<div id="divb" style="display:none;">bbbbbbbbbbbbbbbbbbbbbb</div>
<div id="divc" style="display:none;">cccccccccccccccccccccc</div>
<div id="divd" style="display:none;">dddddddddddddddddddddd</div>
js代码如下:
var lastState = window.location.search.replace(/[?]/g,"");
var eld = $E("d");
var elc = $E("c");
var elb = $E("b");
var ela = $E("a");
ela.onclick = function(){
history.pushState({page: 1}, "title 1", "?page=1"); // 更改链接地址,显示a内容
document.getElementById("diva").style.display = "block";
document.getElementById("divb").style.display = "none";
document.getElementById("divc").style.display = "none";
document.getElementById("divd").style.display = "none";
}
elb.onclick = function(){
history.pushState({page: 2}, "title 2", "?page=2"); // 更改链接地址,显示b内容
document.getElementById("divb").style.display = "block";
document.getElementById("diva").style.display = "none";
document.getElementById("divc").style.display = "none";
document.getElementById("divd").style.display = "none";
}
elc.onclick = function(){
history.pushState({page: 3}, "title 3", "?page=3"); // 更改链接地址,显示c内容
document.getElementById("divc").style.display = "block";
document.getElementById("divb").style.display = "none";
document.getElementById("diva").style.display = "none";
document.getElementById("divd").style.display = "none";
}
eld.onclick = function(){
// history.replaceState({page: 4}, "title 4", "?page=4");
history.pushState({page: 4}, "title 4", "?page=4");
document.getElementById("divd").style.display = "block";
document.getElementById("divb").style.display = "none";
document.getElementById("diva").style.display = "none";
document.getElementById("divc").style.display = "none";
}
window.onpopstate = function(event) { //此时也需要判断当前的查询字符串是否相同,来做不同的操作。
var newState = window.location.search.replace(/[?]/g,"");
if(newState != lastState){
stateChange(lastState = newState)
}
};
function stateChange(url){
switch(url){
case 'page=1':
document.getElementById("diva").style.display = "block";
document.getElementById("divb").style.display = "none";
document.getElementById("divc").style.display = "none";
document.getElementById("divd").style.display = "none";
break;
case 'page=2':
document.getElementById("divb").style.display = "block";
document.getElementById("diva").style.display = "none";
document.getElementById("divc").style.display = "none";
document.getElementById("divd").style.display = "none";
break;
case 'page=3':
document.getElementById("divc").style.display = "block";
document.getElementById("divb").style.display = "none";
document.getElementById("diva").style.display = "none";
document.getElementById("divd").style.display = "none";
break;
case "page=4":
document.getElementById("diva").style.display = "none";
document.getElementById("divb").style.display = "none";
document.getElementById("divc").style.display = "none";
document.getElementById("divd").style.display = "block";
break;
}
};
其实最关键的应该让ie6,7下可以支持,可是我研究了好久都没有弄好,最近强哥在写这个通用的组件,等我研究明白了拿出来在分享吧!
第一次想把自己研究的东西给分出来,虽然不是很好,大家将就这看吧!会改进的!欢迎大家私信我,提出意见!加油!