1. 程式人生 > >Re:從零開始的實習生活04----盤點window物件中location和history

Re:從零開始的實習生活04----盤點window物件中location和history

最近開始移動端頁面的時候,被window.location和window.history坑了一把,於是決定對這兩個物件進行一個全面的剖析。下面進行我們的正文…

location

首先介紹的是location物件,location是BOM物件中最常用的一個物件之一,它提供了與當前視窗中載入的文件的有關的資訊,還提供了一些導航的功能。說到這裡,其實location是一個非常的特別的物件,因為window.location===document.location.另外location對解析URL非常的有幫助,下面看一下location的屬性表。

屬性名 例子 說明
hash “#type” 設定或返回URL中的#後面的hash值,如果沒有則為”“
host “www.google.com:8080” 設定或返回URL中的主機名稱和埠號
hostName “www.google.com” 設定或返回URL中的主機名稱
pathname “/loanOrder/detail” 設定或返回當前 URL 的路徑部分
port “8080” 設定或返回URL中的埠號,如果URL中沒有埠號,則為”“
protocol “http:” 設定或返回當前 URL 的協議,通常是http:或https:
search “?orderId=1236” 返回URL的查詢字串。這個字串以”?”開頭
location屬性表

接下來我們說說,基於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.改變遊覽器的位置

1) window.location.reload() //重新載入頁面

在呼叫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/j35166.html這個是拉勾網上我的公司主頁連結,順道幫忙打個廣告),在控制檯我們執行下面這段程式碼看看。

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()實現同樣的效果了。
*/

結語: 沒什麼是執行一次程式碼不能解決的,如果有那就多執行幾次。