在咱还是初中生的时候,做论坛非常流行“换页不断曲”的页面播放器,简单点说就是框架页面,上面一个Frame是论坛的网址,下面是播放器。
这样做有一个非常明显的弊端:地址栏不会随着论坛页面变化而改变。这是一件非常伤的事情……存书签不方便了,如果你自己的网站有防止被嵌入框架的代码(比如马铃薯、肥鹅微薄就这么干)这种方法会不生效,还有:我初中的时候框架页这种技术就很low了,更别提现在。
所以我们需要一个更加高大上的方法,高大上到低版本IE都无法兼容(σ≧∀≦)σ (在我眼里兼容性一直都是用来吃的,别想太多(゚∀。)
基础知识
我的这个博客就是用了新技术实现了Ajax动态切换内容但是不跳页,至于播放器,还正在实现。一想起要用js写个音量调节滚轮就觉得完全没力气写下去 _(¦3」∠)_
废话不多说了,先看一下我们所需要知道的知识:
获得页面地址栏信息
Window.location
对象,用来存储和URL相关的一切信息,乃可以自己执行一下下面的这段代码体验一下这个对象中究竟包含了多少玩意:
1 | console.log(window.location) |
我们只需要其中的一个:window.location.href
,存储的是一个字符串,内容是地址栏的地址。
得到地址栏后可以使用split方法对内容进行切分,比如我想要得到井号后面的内容,可以这么做:
1 | console.log(window.location.href.split("#")[1]) |
split
是从String
上继承下来的方法,因为太过基础我就不在这里讲太多了,不懂的话可以参考这里。
接下来,说说两个兼容性很差的东西:HTML5的History API。
这货就是能操作地址栏的魔法!(不是Magic code,别想太多……)
一共介绍两个方法一个事件:
先说两个方法:
1 | //向历史记录中添加一个地址 |
深拷贝对象是啥呢,综合犀牛书(Javascript权威指南 第六版 P664 第三行第一个句号往后,包括标题)、MDN、维基百科的信息和公子的讲解,我来做个比较粗浅的解释:如果这个对象能JSON.stringify
就代表它能被序列化、能被深拷贝(눈_눈)。
所谓的深拷贝就是递归复制下某一对象的完整信息,要知道我们在js中如果简单的做下面的操作:
1 | var a = {"baka":"kitkom"} /*nxt line*/ |
b
所包含的内容并不是a
的内容,而是指向a
的一个记号,也就是说我们在改变a.baka
的时候,b.baka
也会随之变化。
深拷贝(也称结构性复制)不同于简单的赋值操作,它完整的拷贝下了这个对象的全部信息;在你重新对原始对象进行操作的时候深拷贝对象是不会跟着变的。
上面的东西如果你看不懂的话可以忽略……
在进行history.push(replace)State
操作的时候,第一个对象会被深拷贝,并存储下来。这样在后退操作的时候,可以读取这个深拷贝对象中的信息,将里面的信息重新放回页面。
这样问题就来了,如果你在pushState
的第一个参数中填入了一个不能被序列化的对象(比如Element,jQuery对象,Function对象)那么就会报错。
一般人是不会傻缺到要保存一个function
的状态,但是试图去保存Element对象或者jQuery对象这种误操作是可能存在的,不要这么做。
这是我之前写代码的时候遇到的问题,所以简单的说一嘴(∑(ι´Дン)ノ哪里简单啊。
不管怎么说,大概就是这么个操作思路ლ(╹◡╹ლ)。
恩,两个方法讲完了,再讲一个事件:popstate
。
当发生了后退操作、前进操作的时候,且push(replace)State
所创建的历史记录序列没到尽头的情况下,会触发popstate
事件;popstate
的event
有一个最重要的属性:state
,返回深拷贝对象。其余的属性我觉的没啥用,不介绍了(´ω)人(´ω)。
在页面加载时,部分浏览器的部分版本会触发popstate
事件(目前我知道的浏览器都不会触发但是火狐的某些版本会(눈_눈))。
—-这句话很重要—->所以安全的做法是在页面准备好之后立刻对页面进行一次replaceState
操作。<—-这句话很重要—-
范例代码
下面我们是不是应该举个栗子?下面的代码是我博客的代码(有删减,注释在对应代码上方或右侧)。
切换页面的操作:
1 | //包含data-ljax的a对象被点击的时候执行下面的操作 |
当浏览器后退的时候进行的操作:
1 | window.onpopstate = function(event) { |
没了,看我码了这么多字,出来的代码却这么少是不是特别不平衡(σ′▽‵)′▽‵)σ。
History 其他方法
最后的最后,History还有back(后退)forward(前进),go(参数为正表示前进,负表示后退)这三个方法,参数为想要跳的步骤,给不知道的同学简单说下,恩。
具体用法:
1 | history.go(-2); |
大概就是这么简单。
那么今天的介绍就到这里=3=~。
Comments
No comments here,
Why not write something?