国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁(yè) 類庫(kù)下載 PHP類庫(kù) 利用pushState, popState和location.hash等方法自己實(shí)現(xiàn)一個(gè)小型路由

利用pushState, popState和location.hash等方法自己實(shí)現(xiàn)一個(gè)小型路由

Oct 31, 2016 pm 02:00 PM

這篇文章主要是記錄下HTML5中history提供的pushState,?replaceStateAPI。最后通過(guò)這些API自己實(shí)現(xiàn)小型的路由。

關(guān)于window.history提供的API請(qǐng)參見(jiàn)Mozilla文檔

其中history提供的pushState和replaceState2個(gè)API提供了操作瀏覽器歷史棧的方法。

其中pushState:

history.pushState(data, null, '#/page=1');
    
    pushState接收3個(gè)參數(shù),第一個(gè)參數(shù)為一個(gè)obj,表示瀏覽器
    
    第二個(gè)參數(shù)是document.title的值,一般設(shè)定為`null`
    
    第三個(gè)參數(shù)string,用以改變 當(dāng)前url

pushState方法在改變url的同時(shí)向?yàn)g覽器歷史棧中壓入新的歷史記錄。

接收url的參數(shù)為string類型,用以改變當(dāng)前地址欄的url.需要注意的一點(diǎn)就是這個(gè)參數(shù)不能和跨域,即協(xié)議,域名,端口必須都是相同的,如果出現(xiàn)跨域的情況,即會(huì)提示:

Uncaught DOMException: Failed to execute 'pushState' on 'History': A history state object with URL 'http://www.baidu.com/' cannot be created in a document with origin 'http://commanderXL.com' and URL

Example:

打開(kāi)www.baidu.com

    history.pushState(null, null, '?page=1')    //地址欄變成 www.baidu.com/?page=1
    
    history.pushState(null, null, '#page=2');    //地址欄變成 www.baidu.com/#page=2

其中replaceState:

history.replaceState(null, null, '#page=2');

replaceState接收的參數(shù)pushState相同,但是最終的效果是:地址欄url會(huì)根據(jù)接收的參數(shù)而變化,但是瀏覽器并未在當(dāng)瀏覽歷史棧中增加瀏覽器的歷史記錄,而是替換當(dāng)前的瀏覽器歷史記錄。

通過(guò)pushState和replaceState雖然能改變URL,但是不會(huì)主動(dòng)觸發(fā)瀏覽器reload。

window對(duì)象還提供popstate方法:

window.addEventListener('popstate', function() {
        
    });

這個(gè)方法用以監(jiān)聽(tīng)瀏覽器在不同歷史記錄中進(jìn)行切換,而觸發(fā)相應(yīng)的事件。

在瀏覽器提供的history對(duì)象上還有g(shù)o, back方法,用以模擬用戶點(diǎn)擊瀏覽器的前進(jìn)后退按鈕。在某個(gè)web應(yīng)用當(dāng)中,比如點(diǎn)擊了標(biāo)簽,發(fā)生了頁(yè)面的跳轉(zhuǎn)。這時(shí)調(diào)用history.back();方法后頁(yè)面回退,同時(shí)頁(yè)面發(fā)生刷新,這時(shí)window.onpopstate無(wú)法監(jiān)聽(tīng)這個(gè)事件。但是如果是通過(guò)pushState或者replaceState來(lái)改變URL且不發(fā)生瀏覽器刷新的話,再使用history.back()或history.go(),這樣popstate事件會(huì)被觸發(fā)。

history.pushState({page: 1}, null, '?page=1');
    history.pushState({page: 2}, null, '?page=2');

    history.back(); //瀏覽器后退

    window.addEventListener('popstate', function(e) {        //在popstate事件觸發(fā)后,事件對(duì)象event保存了當(dāng)前瀏覽器歷史記錄的狀態(tài).
        //e.state保存了pushState添加的state的引用
        console.log(e.state);  //輸出 {page: 1}
    });

PS: 通過(guò)pushState在url上添加?page=1可以通過(guò)location.search去獲取search的內(nèi)容。不過(guò)如果通過(guò)location.search去改變url的話是會(huì)主動(dòng)觸發(fā)瀏覽器reload的。這個(gè)特性可以和下面將的關(guān)于hash的內(nèi)容對(duì)比下。

API大致了解了,那么這些方法可以運(yùn)用到哪些地方呢?一個(gè)比較常用的場(chǎng)景是就在單頁(yè)應(yīng)用中,通過(guò)這些API完成前端的路由設(shè)計(jì),利用pushState, replaceState可以改變url同時(shí)瀏覽器不刷新,并且通過(guò)popstate監(jiān)聽(tīng)瀏覽器歷史記錄的方式,完成一系列的異步動(dòng)作。

addRoute('/login', function() {
        //do something
    })
    
    
    //路由處理
    const routeHandle = (path) => {
        Router.forEach((item, index) => {
            if(item.path === path) {
                item.handle.apply(null, [path]);
                return true;
            }
        })
        return false;
    }
    
    
    //攔截默認(rèn)的a標(biāo)簽行為
    document.addEventListener('click', function(e) {
        let dataset = e.target.dataset;
        if(dataset) {
            if(routeHandle(dataset.href)) {
                //阻止默認(rèn)行為
                e.preventDefault();
            }
        }
    })

大致的實(shí)現(xiàn)思路就是,通過(guò)添加路由信息,然后攔截標(biāo)簽的默認(rèn)行為,并與注冊(cè)的路由信息進(jìn)行匹配。若匹配成功調(diào)用對(duì)應(yīng)的handle方法.

不過(guò)pushState和replaceState方法在低版本的IE瀏覽器下兼容性不是很好。所以可以進(jìn)行降級(jí)使用hash來(lái)進(jìn)行路由設(shè)計(jì)。

hash?請(qǐng)戳我。

可以通過(guò)location.hash獲取url上第一個(gè)#(fragment)及后面的內(nèi)容。同時(shí)還能通過(guò)location.hash改寫(xiě)其內(nèi)容,且不會(huì)主動(dòng)觸發(fā)瀏覽器reload。 有些功能是不是和pushState和replaceState一樣? 所以為了兼容到低版本的瀏覽器,可以通過(guò)監(jiān)聽(tīng)#變化來(lái)進(jìn)行路由設(shè)計(jì)。

那么如何去監(jiān)聽(tīng)呢? 比較粗暴的一種方式就是polling。

var oldHash = location.hash;
    setTimeInterval(function() {        if(oldHash !== location.hash) {            
            //do something
        
            oldHash = location.hash;
        }
    }, 100);

不過(guò),H5還提供了一個(gè)API: hashchange。它的就可以直接代替上面的polling方法,來(lái)監(jiān)聽(tīng)#的變化。

window.addEventListener('hashchange', function() {
        routeHandle(locaiton.hash);
    });

這個(gè)小型的路由設(shè)計(jì)可以參見(jiàn)我的github.

稍微總結(jié)下:

上面主要介紹了history提供的一些API,hash的相關(guān)知識(shí)。在平時(shí)可以運(yùn)用到SPA當(dāng)中,Gmail就是通過(guò)hash來(lái)進(jìn)行路由設(shè)計(jì)的。它相對(duì)于頁(yè)面跳轉(zhuǎn)來(lái)說(shuō):

頁(yè)面只需要加載一次。后面的頁(yè)面切換可以通過(guò)ajax去請(qǐng)求數(shù)據(jù)。頁(yè)面體驗(yàn)更加流暢;

可以利用本地緩存,優(yōu)化頁(yè)面體驗(yàn)。在不同頁(yè)面切換的過(guò)程中更加流暢;

可進(jìn)行按需加載...

等等一些實(shí)用的好處吧。

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請(qǐng)聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機(jī)

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強(qiáng)大的PHP集成開(kāi)發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)代碼編輯軟件(SublimeText3)

熱門(mén)話題

Laravel 教程
1600
29
PHP教程
1502
276