JS中最容易被轻视的对象----location和history

最近开始移动端页面的时候,被window.location和window.history坑了一把,因而决定对这两个对象进行一个全面的剖析。下面进行咱们的正文...html

locationweb

首先介绍的是location对象,location是BOM对象中最经常使用的一个对象之一,它提供了与当前窗口中加载的文档的有关的信息,还提供了一些导航的功能。说到这里,其实location是一个很是的特别的对象,由于window.location===document.location.另外location对解析URL很是的有帮助,下面看一下location的属性表。跨域

以此例子:http://www.google.com:8080/lo... (注:随便打的)数组

属性名 例子 说明
hash "#type" 设置或返回URL中的#后面的hash值,若是没有则为""
host "www.google.com:8080" 设置或返回URL中的主机名称和端口号
hostName "www.google.com" 设置或返回URL中的主机名称
href "http://www.google.com:8080/loanOrder/detail?orderId=1236#type" 设置或返回完整的URL
pathname "/loanOrder/detail" 设置或返回当前 URL 的路径部分
port "8080" 设置或返回URL中的端口号,若是URL中没有端口号,则为""
protocol "http:" 设置或返回当前 URL 的协议,一般是http:或https:
search "?orderId=1236" 返回URL的查询字符串。这个字符串以"?"开头

<center>location属性表</center>浏览器


接下来咱们说说,基于location对象咱们经常使用的一些操做。缓存

1.查询字符串参数服务器

function getArgsQuery() {
        //取得查询字符串并去掉"?"
        var searchStr=window.location.search.length>0?window.location.search.substring(1):"";
        //将每一项集成到数组中
        var searchStrArray=searchStr.length>0?searchStr.split("&"):[];
        //存储最后返回的对象
        var args={};
        searchStrArray.forEach(function (item) {
            //属性
            var name=decodeURIComponent(item.split("=")[0]);
            //值
            var value=decodeURIComponent(item.split("=")[1]);
            args[name]=value;
        });
        return args;
    }

2.改变游览器的位置google

1) window.location.reload() //从新加载页面url

在调用reload()不传任何参数时,页面自上次请求以来并无改变过,页面就会从游览器缓存中加载,若是传入参数true时,页面会强制从服务器从新加载。

例:
 window.location.reload()  //从新加载(有可能从缓存中加载)
 window.location.reload(true) //从新加载(从服务器从新加载)

2) window.location.assign(url); //加载新的文档设计

与 window.location.assign(url)效果同样的还有

 - window.location.href=url;
 - window.location=url;

3) window.location.replace(url); //用新文档替换当前文档

一样是加载新文档,区别就是window.location.assign(url)是能够重新文档再回到当前文档,可是window.location.replace(url)就不行了,用来实现过渡页面时很是好用,可是有些webview倒是不支持的,好比小编在开发的钉钉上的微应用的时候就遇到这个,这时咱们该如何作呢?下面就是咱们讲到的history对象。

history

History 对象最初设计来表示窗口的浏览历史。但出于隐私方面的缘由,History 对象再也不容许脚本访问已经访问过的实际 URL。惟一保持使用的功能只有 back()、forward() 和 go() 方法。这三个也很是简单,我就随便写几个例子,意思一下。

例子:
       
    window.history.go(-2);  //后退两页   
    window.history.go(-1);  //后退一页   
    window.history.go(1);   //前进一页
    window.history.go(2);   //前进两页
   
    window.history.back();//后退一页
    window.history.forward();//前进一页

这里要说一下的是window.history.go(),我在查阅资料的时候发现window.history.go()是能够传一个字符串参数的,此时的游览器会跳转到历史记录中包含该字符串的第一个位置(可能前进可能后退)。小编一开始倒是也不知道这个,就本身试了一下,可是页面就刷新了一下,并无匹配到页面,小编试了好几回,也换了好几个游览器也没有成功,若是其余小伙们成功,还望留言告知。


上面三个方面相信不少人都知道,可是小编要介绍的是下面这两个方法:window.history.pushState()和 window.history.replaceState().

1) window.history.pushState(stateObject,title,url )

将当前URL和history.state加入到history中,并用新的state和URL替换当前,不会形成页面刷新。

--参数解释
stateObject    //与要跳转到的URL对应的状态信息,没有特殊的状况下能够直接传{}
title       //如今大多数浏览器不支持或者忽略这个参数,咱们在用的时候建议传一个空字符串
url            //这个参数提供了新历史纪录的地址,它不必定要是绝对地址,也能够是相对的,不可跨域

2) window.history.replaceState(stateObject,title,url)

用新的state和URL替换当前,不会形成页面刷新。

--参数解释
stateObject    //与要跳转到的URL对应的状态信息,没有特殊的状况下能够直接传{}
title       //如今大多数浏览器不支持或者忽略这个参数,咱们在用的时候建议传一个空字符串
url            //这个参数提供了新历史纪录的地址,它不必定要是绝对地址,也能够是相对的,不可跨域

有些小伙伴们看到这里可能对stateObject这个参数不太清楚,下面咱们举个例子来体会这个stateObject是怎么回事。说到这个,我先说一下popstate事件,这个事件是干吗的,或者怎样才能触发的,官方给咱们的答案是:

popstate每次活动历史记录条目在同一文档的两个历史记录条目之间改变时,将事件分派到窗口。

可能不少人跟我同样,看到这个解释的时候一脸懵逼的,那咱们就简单的,哪些方法能够触发这个popstate事件。下面打开这个连接https://www.lagou.com/gongsi/...这个是拉勾网上个人公司主页连接,顺道帮忙打个广告),在控制台咱们执行下面这段代码看看。

window.onpopstate = function(event) {
    alert("location: " + document.location + ", state: " + JSON.stringify(event.state));
};
window.history.pushState({name:"阿里巴巴"}, "", "347.html");
window.history.pushState({name: "支付宝"}, "", "164268.html");
window.history.replaceState({name: "华为"}, "", "j87078.html");

window.history.back(); // alert "location: https://www.lagou.com/gongsi/347.html, state: {"name":"阿里巴巴"}"
console.log(window.history.state);//{name:"阿里巴巴"}

window.history.back(); // alert "location: https://www.lagou.com/gongsi/35166.html, state: null
console.log(window.history.state);//null

window.history.go(2);  // alert "location: https://www.lagou.com/gongsi/j87078.html, state: {"name":"华为"}
console.log(window.history.state);//{name:"华为"}

相信执行这段代码以后,你就更好理解了,没什么是执行一次代码不能解决的,若是有那就多执行几回。
回到前面我抛出的问题,怎么替代window.location.replace()方法,可能很多小伙们已经知道了,不知道的小伙们,我就贴一下例子:

/*
    可能还有其余的方法,若是有欢迎留言交流
    这里我依旧拿https://www.lagou.com/gongsi/j35166.html举例
    打开控制台,输入下面这段代码。
*/
history.replaceState({name: "华为"}, "", "j87078.html");
window.location.reload();

/*
执行完以后,咱们发现不能回退了,是否是就跟window.location.replace()实现一样的效果了。
*/

结语: 没什么是执行一次代码不能解决的,若是有那就多执行几回。