JS實現無重新整理圖片預覽

2020-07-16 10:05:09
本例設計一個簡單的圖片畫廊,它使用 History API 作為介面,展示了一個圖片預覽模式:一個具有相關性的圖片無重新整理存取。在支援的瀏覽器中瀏覽,單擊下一張圖片畫廊的連結將更新照片和更新 URL 地址,沒有引發全頁面重新整理。在不支援的瀏覽器中,或者當使用者禁用了指令碼時,導航連結只是作為普通連結,會開啟一個新的頁面,整頁重新整理。

操作步驟

1) 建立網頁文件。本例圖片畫廊包含系列 HTML 文件,這些文件結構相同,確保在關閉指令碼的情況下能否順暢存取。包含檔案:adagio.html、angie.html、brandy.html、casey.html、fer.html、pepper.html、willie.html。這些檔案都可以獨立執行,在網站中屬於平級關係。通過圖片畫廊的連結可以相互存取。

2) 設計文件結構。上述檔案包含相同的 HTML 結構。核心結構如下:
<aside id="gallery">
    <p class="photonav"><a id="photonext" href="pepper.html">下一張</a><a id="photorev" href="brandy.html">&lt; 上一張</a></p>
    <figure id="photo"><img id="photoimg" src="gallery/1989-willie-500.jpg" alt="Willie" width="500" height="375">
        <figcaption>Willie,1989</figcaption>
    </figure>
</aside>
與本例相關的程式碼位於 <aside id="gallery"> 包含框中,它由一個 <p> 標籤包含的導航連結、一個 <figure> 標籤包含的圖片,以及一個 <figcaption> 標籤包含的圖片說明文字組成。其他幾個檔案的結構相同,但是位於 <aside id="gallery"> 包含框中的資訊不同。

3) 根據圖片畫廊的相關文件結構和內容,在 gallery 資料夾中對映一組非同步請求的文件片段,對應檔名為:adagio.html、angie.html、brandy.html、casey.html、fer.html、pepper.html、willie.html。這些檔案不能獨立執行,僅作為 Ajax 非同步請求的文件片段進行載入。

4) 設計文件片段的 HTML 程式碼結構。這些文件片段檔案實際上是圖片畫廊系列檔案中 <aside id="gallery"> 包含的 HTML 字串提取。例如 gallery/adagio.html 文件,程式碼如下:
<p class="photonav"><a id="photonext" href="angie.html">下一張></a><a id="photoprev" href="pepper.html">&lt; 上一張</a></p>
<figure id="photo"><img id="photoimg" src="gallery/1995-adagio-500.jpg" alt="Adagio" width="500" height="375">
    <figcaption>Adagio,1995</figcaption>
</figure>

5) 完成整個圖片畫廊文件結構設計。下面重點介紹 JavaScript 指令碼部分,新建 JavaScript 檔案,儲存為 gallery.js。

6) 為圖片畫廊的超連結系結 click 事件處理程式。在處理常式中,先執行 Ajax 非同步切換圖片顯示,如果成功,則呼叫 history.pushState() 方法,在瀏覽器歷史記錄中新增一條瀏覽記錄,同時阻止超連結預設的跳轉行為。
function addClicker (link) {
    link.addEventListener ("click", function (e) {
        if (swapPhoto (link.href)) {
            history.pushState (null, null, link.href);
            e.preventDefault ();
        }
    }, true);
}
function setupHistoryClicks () {
    addClicker (document.getElementById("photonext"));
    addClicker (document.getElementById("photoprev"));
}

7) 設計非同步切換圖片畫廊顯示。根據超連結的 href 屬性值,使用 Ajax 開啟 gallery 目錄下對應的目標檔案,如果開啟成功,則把請求的文件片段寫入 <aside id="gallery"> 容器中,同時呼叫上一步定義的 setupHistoryClicks() 函數,為新頁面超連結系結 click 事件處理程式。
function swapPhoto (href) {
    var req = new XMLHttpRequest ();
    req.open ("GET", "gallery/" + href.split("/").pop(), false);
    req.send (null);
    if (req.status == 200) {
        document.getElementById ("gallery").innerHTML = req.responseText;
        setupHistoryClicks ();
        return true;
    }
    return false;
}

8) 在頁面初始化事件處理常式中,對頁面載入的導航連結系結 click 事件處理程式,同時註冊 popstate 事件,監聽瀏覽器歷史記錄的更新狀態,如果發生變化,則呼叫 swapPhoto() 函數把圖片畫廊切換到對應的頁面。
window.onload = function () {
    if (! supports_history_api()) { return; }
    setupHistoryClicks ();
    window.setTimeout (function () {
        window.addEventListener ("popstate", function (e) {
            swapPhoto (location.pathname);
        }, false);
    }, 1);
}
執行效果如下圖所示: