成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

前端:將網(wǎng)站打造成單頁(yè)面應(yīng)用SPA(一)

youkede / 2667人閱讀

摘要:可以在各個(gè)頁(yè)面間傳遞數(shù)據(jù),不依賴??梢赃x擇性的保留狀態(tài),如音樂網(wǎng)站,切換頁(yè)面時(shí)不會(huì)停止播放歌曲。減少了請(qǐng)求體積,節(jié)省流量,加快頁(yè)面響應(yīng)速度。將返回的替換到頁(yè)面中。不過這個(gè)參數(shù)目前并無(wú)作用,瀏覽器目前會(huì)選擇忽略它。

前言

不知你有沒有發(fā)現(xiàn),像Github、百度、微博等這些大站,已經(jīng)不再使用普通的a標(biāo)簽做跳轉(zhuǎn)了。他們大多使用Ajax請(qǐng)求替代了a標(biāo)簽的默認(rèn)跳轉(zhuǎn),然后使用HTML5的新API修改了Url,你可以在F12的Network面板里發(fā)現(xiàn)這個(gè)秘密。

這項(xiàng)技術(shù)并沒有特別標(biāo)準(zhǔn)的學(xué)名,大家都稱呼為Pjax,意為PushState + Ajax。這并不完全準(zhǔn)確,因?yàn)檫€有Hash + Ajax等方法,但為了方便,我們下文還是統(tǒng)稱為Pjax。

為什么要這么做?

Pjax是一個(gè)優(yōu)秀的解決方案,你有足夠多的理由來使用它:

可以在頁(yè)面切換間平滑過渡,增加Loading動(dòng)畫。

可以在各個(gè)頁(yè)面間傳遞數(shù)據(jù),不依賴URL。

可以選擇性的保留狀態(tài),如音樂網(wǎng)站,切換頁(yè)面時(shí)不會(huì)停止播放歌曲。

所有的標(biāo)簽都可以用來跳轉(zhuǎn),不僅僅是a標(biāo)簽。

避免了公共JS的反復(fù)執(zhí)行,如無(wú)需在各個(gè)頁(yè)面打開時(shí)都判斷是否登錄過等等。

減少了請(qǐng)求體積,節(jié)省流量,加快頁(yè)面響應(yīng)速度。

平滑降級(jí)到低版本瀏覽器上,對(duì)SEO也不會(huì)有影響。

原理呢?

Pjax的原理十分簡(jiǎn)單。
1. 攔截a標(biāo)簽的默認(rèn)跳轉(zhuǎn)動(dòng)作。
2. 使用Ajax請(qǐng)求新頁(yè)面。
3. 將返回的Html替換到頁(yè)面中。
4. 使用HTML5的History API或者Url的Hash修改Url。

HTML5 History API

我們來看看HTML5在History里增加了什么:

history.pushState(state, title, url)

pushState方法會(huì)將當(dāng)前的url添加到歷史記錄中,然后修改當(dāng)前url為新url。請(qǐng)注意,這個(gè)方法只會(huì)修改地址欄的Url顯示,但并不會(huì)發(fā)出任何請(qǐng)求。我們正是基于此特性來實(shí)現(xiàn)Pjax。它有3個(gè)參數(shù):

state: 可以放任意你想放的數(shù)據(jù),它將附加到新url上,作為該頁(yè)面信息的一個(gè)補(bǔ)充。

title: 顧名思義,就是document.title。不過這個(gè)參數(shù)目前并無(wú)作用,瀏覽器目前會(huì)選擇忽略它。

url: 新url,也就是你要顯示在地址欄上的url。

history.replaceState(state, title, url)

replaceState方法與pushState大同小異,區(qū)別只在于pushState會(huì)將當(dāng)前url添加到歷史記錄,之后再修改url,而replaceState只是修改url,不添加歷史記錄。

window.onpopstate 事件
一般來說,每當(dāng)url變動(dòng)時(shí),popstate事件都會(huì)被觸發(fā)。但若是調(diào)用pushState來修改url,該事件則不會(huì)觸發(fā),因此,我們可以把它用作瀏覽器的前進(jìn)后退事件。該事件有一個(gè)參數(shù),就是上文pushState方法的第一個(gè)參數(shù)state。

一個(gè)實(shí)例:

這里我們以daipig為例,打開daipig,地址欄是http://www.daipig.com 。接下來打開F12 Console,輸入:

history.pushState({ a: 1, b: 2 }, null, "http://www.daipig.com/abcdefg");

可以發(fā)現(xiàn),url已經(jīng)變成我們輸入的url了,但頁(yè)面并沒有刷新,也沒有發(fā)出任何請(qǐng)求?,F(xiàn)在再輸入history.state,就可以看到我們剛剛傳過來的第一個(gè)參數(shù)state了。

這時(shí)點(diǎn)擊后退,url會(huì)回到www.daipig.com,同樣是沒有刷新。只不過后退的時(shí)候其實(shí)是觸發(fā)了window.onpopstate事件的。

詳細(xì)文檔可以查閱MDN: https://developer.mozilla.org/zh-CN/docs/DOM/Manipulating_the_browser_...

怎么完整的實(shí)現(xiàn)Pjax?

Pjax的原理上文已經(jīng)講了,并不復(fù)雜。我實(shí)現(xiàn)了一個(gè)比較粗糙的Pjax庫(kù),已經(jīng)能滿足不少需求,如果你有興趣,可以上Github幫忙完善一下代碼。地址是:https://github.com/Coffcer/coffce-pjax 。

完整的代碼見Github,這里我們只談需要注意的一些地方。

匹配選擇器

要實(shí)現(xiàn)Pjax,難免就會(huì)有匹配選擇器的需求。你需要判斷當(dāng)前點(diǎn)擊的元素,是否匹配指定選擇器。這里我給出一個(gè)兼容至IE8的解決方法:

// 判斷element是否匹配選擇器selector
function matchSelector(element, selector) {
    var match = 
        document.documentElement.webkitMatchesSelector || 
        document.documentElement.mozMatchesSelector || 
        document.documentElement.msMatchesSelector ||
        // 兼容IE8及以下瀏覽器
        function(selector, element) {
            // 這是一個(gè)好方法,可惜IE8連indexOf都不支持
            // return Array.prototype.indexOf.call(document.querySelectorAll(selector), this) !== -1;

            if (element.tagName === selector.toUpperCase()) return true;

            var elements = document.querySelectorAll(selector),
            length = elements.length;

            while (length--) {
            if (elements[length] === this) return true;
            }

            return false;
        };

    // 重寫函數(shù)自身,使用閉包keep住match函數(shù),不用每次都判斷兼容
    matchSelector = function(element, selector) {
        return match.call(element, selector);
    };

    return matchSelector(element, selector);
}
// 驗(yàn)證一下
matchSelector(document.getElementById("abc"), "#abc"); // true
matchSelector(document.querySelector("a"), "p"); // false

在現(xiàn)代瀏覽器上,優(yōu)先使用原生的matchesSelector方法來判斷,在IE8及以下的瀏覽器里,循環(huán)document.querySelector的結(jié)果集,依次對(duì)比。

這個(gè)方法利用了閉包,然后重寫自身,只有在第一次調(diào)用時(shí)需要判斷加哪個(gè)前綴執(zhí)行哪個(gè)方法,其后都是調(diào)用了閉包的match函數(shù)。

不支持HTML5 PushState的瀏覽器怎么辦?

IE6到IE9是不支持pushState的,要修改Url,只能利用Url的Hash,也即是#號(hào)。

你可以隨意找個(gè)網(wǎng)站試一下,在url后面加上#號(hào)和任意內(nèi)容,頁(yè)面并不會(huì)刷新。此時(shí)點(diǎn)擊后退也只會(huì)回到上一條#號(hào),同樣不會(huì)刷新。

那么我們只需把pushState(新url)換成localtion.hash = 新url,把onpopstate事件換成onhashchange事件就可以兼容IE了。
QQ音樂,網(wǎng)易云音樂等就是使用這種方式。

現(xiàn)成的庫(kù)

我簡(jiǎn)單實(shí)現(xiàn)了一個(gè)比較粗糙的Pjax庫(kù),地址是:https://github.com/Coffcer/coffce-pjax ,歡迎PR和Star。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/85759.html

相關(guān)文章

  • 前端歷史演變

    摘要:在選擇學(xué)習(xí)之前,我們先了解一下前端整個(gè)發(fā)展歷程?,F(xiàn)在回顧一下前端到底發(fā)生了哪些歷史變化。階段年技術(shù)的誕生改變了前端的發(fā)展歷史。前端開始慢慢向后端靠攏。 在選擇學(xué)習(xí)Webpack之前,我們先了解一下前端整個(gè)發(fā)展歷程。 showImg(https://segmentfault.com/img/remote/1460000019650483?w=1830&h=504);2014年初,我加入互...

    meislzhua 評(píng)論0 收藏0
  • 前端最實(shí)用書簽(持續(xù)更新)

    摘要:前言一直混跡社區(qū)突然發(fā)現(xiàn)自己收藏了不少好文但是管理起來有點(diǎn)混亂所以將前端主流技術(shù)做了一個(gè)書簽整理不求最多最全但求最實(shí)用。 前言 一直混跡社區(qū),突然發(fā)現(xiàn)自己收藏了不少好文但是管理起來有點(diǎn)混亂; 所以將前端主流技術(shù)做了一個(gè)書簽整理,不求最多最全,但求最實(shí)用。 書簽源碼 書簽導(dǎo)入瀏覽器效果截圖showImg(https://segmentfault.com/img/bVbg41b?w=107...

    sshe 評(píng)論0 收藏0
  • 利用K8S技術(shù)棧打造個(gè)人私有云(連載之:私有云客戶端打造

    摘要:前端技術(shù)棧還是非常龐大的,為了能夠借助已經(jīng)存在的輪子來造出一輛車,所以我選擇了進(jìn)行實(shí)踐。狀態(tài)的管理的狀態(tài)管理依靠完成,用其來管理的所有組件狀態(tài)。私有云客戶端打造主頁(yè)面首先是主頁(yè)面,可以打開任何一個(gè)云主機(jī)系統(tǒng)的頁(yè)面看,基本類似。 showImg(https://segmentfault.com/img/remote/1460000013930354); 【利用K8S技術(shù)棧打造個(gè)人私有...

    Jingbin_ 評(píng)論0 收藏0
  • 利用K8S技術(shù)棧打造個(gè)人私有云(連載之:私有云客戶端打造

    摘要:前端技術(shù)棧還是非常龐大的,為了能夠借助已經(jīng)存在的輪子來造出一輛車,所以我選擇了進(jìn)行實(shí)踐。狀態(tài)的管理的狀態(tài)管理依靠完成,用其來管理的所有組件狀態(tài)。私有云客戶端打造主頁(yè)面首先是主頁(yè)面,可以打開任何一個(gè)云主機(jī)系統(tǒng)的頁(yè)面看,基本類似。 showImg(https://segmentfault.com/img/remote/1460000013930354); 【利用K8S技術(shù)棧打造個(gè)人私有...

    shiina 評(píng)論0 收藏0
  • 前端資源收集整理

    摘要:工作原因,最近一年斷斷續(xù)續(xù)寫了一點(diǎn)前端代碼,收集整理了一些資料,和大家共享。 工作原因,最近一年斷斷續(xù)續(xù)寫了一點(diǎn)前端代碼,收集整理了一些資料,和大家共享。 Github版本:Front-End Resource Collection 前端相關(guān)資源匯總 學(xué)習(xí)指導(dǎo) 精華文章 Web前端的路該怎么走?:文章超長(zhǎng),但是干貨超級(jí)多,值得反復(fù)精讀! 聽說2017你想寫前端?:適合于已經(jīng)度過了小白階...

    awesome23 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

youkede

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<