本文適用於 Laravel 5.0 以上版本。
簡單來說,以往使用的 AJAX
可以不重新載入網頁,異步載入伺服器的資料,並更新畫面。而 PJAX
則是加入了 HTML5 的 PushState
技術,在取得資料的同時改變 Url,可以保留瀏覽器上一頁的功能,而且不會從伺服器重新載入 js 及 css 之類的靜態檔案,加快網頁的載入速度。
jacobbennett/pjax
在 Laravel 我們需要安裝 jacobbennett/pjax
這隻 Package(Github),他會根據 Request 是否為 PJAX 來回傳對應資料。安裝請直接修改 composer.json
:
..."require": {..."jacobbennett/pjax": "0.*",}...
接著執行 composer update
或是 composer install
安裝 package。
安裝完成後,我們要把 jacobbennett/pjax
的 middleware 加到我們預設的 middleware 中,打開 app/Http/Kernel.php
,在 $middleware
增加:
...protected $middleware = [...'JacobBennett\Pjax\PjaxMiddleware',];...
這樣 Laravel 的部分就準備完成了。
jQuery.pjax
前端部分使用 jQuery.pjax
這隻 Library,jQuery.pjax
是基於 jQuery,並封裝了 pushState 與 AJAX ,讓你更容易使用 PJAX 的 Library,關於此 Library 可以參閱 jQuery.pjax 的 Github。另外 jQuery.pjax
依賴於 jQuery 1.8.x
以上,所以安裝前請確保你的專案有載入 jQuery
。
下載 jquery.pjax.js
至你的專案中,本範例下載至專案的 /public/javascripts
資料夾,我習慣使用 wget
,你可以使用你習慣的方式下載,像是 curl
或是直接用瀏覽器:
$ wget -P public/javascripts https://raw.github.com/defunkt/jquery-pjax/master/jquery.pjax.js
接著在你的 views
中載入檔案:
<script src="{{ assets('javascripts/jquery.pjax.js') }}"></script>
最後增加 JavaScript:
$(document).ready(function () {$(document).pjax('a', 'body');});
上方程式的第一個參數代表會攔截所有的 a
標籤,若瀏覽器有支援就改以 PJAX 的方式送出,第二個參數代表接收到的資料替換至 body
。
另外,PushState 有瀏覽器支援的問題(萬惡的 IE),支援度可以至 Can I use 查看,不過這不用擔心,若瀏覽器不支援 PushState,就會以原始方式打開超連結。
完成上面的步驟後你的專案就擁有 PJAX 的功能了,打開 Devtools 的 Network 畫面,點擊任一 a
標籤,就會看到帶有 _pjax=body
的 Request ,接著畫面就會更新了!
不過這樣的 UX 不是很好,有時點擊連結後有某些原因造成等待的時間較久,使用者可能覺得沒反應就會重新載入,或是重複點擊,這樣的效果並不好,所以我們要加上載入動畫,實作效果可以參考 Youtube(下圖畫面上方的紅色讀取條)。
nprogress.js
是一個載入動畫的 Library,效果可以參考它的官方網站,也可在它的 Github 參考使用的 API。
下載檔案至專案中:
$ wget -P public/javascripts http://ricostacruz.com/nprogress/nprogress.js$ wget -P public/stylesheets http://ricostacruz.com/nprogress/nprogress.css
接著在 views
載入檔案:
<link rel="stylesheet" href="{{ asset('stylesheets/nprogress.css') }}"><script src="{{ assets('javascripts/nprogress.js') }}"></script>
最後把效果加到 PJAX 的生命週期中:
$(document).ready(function () {$(document).pjax('a', 'body');$(document).on('pjax:start', function () {NProgress.start();});$(document).on('pjax:end', function () {NProgress.done();});});
至此你的專案已經擁有完整的 PJAX 了!
Q:我不喜歡 nprogress 的效果,有沒有別的可以用? A:你可以考慮使用 PACE、Progress.js,不過我都沒使用過,但方式應該是大同小異。
Q:為什麼我的一些 JavaScript Library 會爆掉沒反應?
A:你使用的 Library 如果需要在畫面載入完時重新初始化(像是 portfolio.js),請把相關程式碼放入 PJAX
的生命週期中,如下:
$(document).on('pjax:end', function () {initPortfolio();NProgress.done();});
有其他問題也可以留言,我會盡力幫助你的 :)
References: PHPHub
← Back to Home