2014-04-07 30 views
0

我正在嘗試解決模態問題。我想要做的是允許用戶點擊瀏覽器的後退按鈕來關閉模式並返回到頁面的原始狀態,這是:無模式。爲了這個目的,我想到了使用HTML 5歷史API。基礎揭示模式和HTML5歷史API操作

我開始試圖追加查詢字符串參數的URL,比如http://...page.html?show_modal=[yes|no]但是我最終離開這個方法,因爲我無法處理所有涉及popstate事件,pageshow事件等我不能」的東西不要讓它工作,它會讓我不知所措。

然後我嘗試了一個更簡單的方法,其中包括一個附加到URL的散列,例如http://...page.html#modalhashchange事件。這種方法對我來說效果更好,我幾乎擁有它。

當用戶單擊按鈕顯示模式時,他或她可以單擊瀏覽器的後退按鈕,它將關閉模式。此外,之後,用戶可以點擊瀏覽器的前進按鈕,它會再次顯示模式。非常好!用戶也可以直接導航到帶有散列的URL,以直接訪問頁面的這種狀態,以及他或她可以爲頁面的這種狀態添加書籤。它的工作非常整齊,我對結果感到非常滿意。

問題是,它不完全完美。當用戶通過點擊背景,ESC鍵或右上角的X來消除模式時,歷史開始混亂。嘗試一下:點擊按鈕打開模式,然後點擊背景將其解除(看看地址欄中的URL,這裏的第一個問題是沒有移除哈希),然後點擊您的瀏覽器後退按鈕,您會看到它不能正常工作。您將以歷史記錄中的副本結束,並且必須點擊後退按鈕兩次才能轉至上一頁。從UX的角度來看,這是不可取的。有沒有人知道這個解決方案?

我在此提供我的代碼CodePen和這個問題的結尾。我建議在你自己的機器上嘗試它,而不是在Codepen中,所以你可以在URL中查看哈希等。另外,它不能在Codepen Full模式下工作,我不知道爲什麼。

謝謝!

我使用基金會5.2.1

HTML

<div class="row"> 
    <div class="small-12 columns"> 
    <h1>Reveal Modal</h1> 
    <h2>Manipulation of the browser history for a better UX</h2> 
    <a class="button radius" href="#" data-reveal-id="sampleModal" id="button">Show Modal...</a> 
    </div> 
</div> 
<!-- ############# --> 
<!--  MODAL  --> 
<!-- ############# --> 
<div id="sampleModal" class="reveal-modal medium" data-reveal> 
    <h2>Hi!</h2> 
    <p>You may think you are on a new page now, but you aren't. Try to click your browser <kbd>Back</kbd> button to dismiss this modal and return to the the page you were viewing.</p> 
    <a class="close-reveal-modal">&times;</a> 
</div> 

的JavaScript

function setModalHash(url, present) { 
    var a = $('<a>', { href:url })[0]; // http://tutorialzine.com/2013/07/quick-tip-parse-urls/ 
    var newHash = ""; 
    if (present === true) { 
    newHash = "#modal"; 
    } 
    // Build the resulting URL 
    result = a.protocol + "//" + a.hostname + ":" + a.port + a.pathname + a.search + newHash; 

    return result; 
} 

$("#button").on('click', function() { 
    history.pushState(null, null, setModalHash(document.URL, true));   
});  

$(window).on("hashchange load",function(e) { 
    // Handling also the load event allows navigation directly to http://host/path/to/file#modal and bookmarking it 
    if (document.location.hash == "#modal") { 
    $("#sampleModal").foundation("reveal","open"); 
    } 
    else { 
    $("#sampleModal").foundation("reveal","close"); 
    } 
}); 

回答

0

我已經搞亂歷史API/History.js與會話存儲組合保持模態狀態,並基於用戶導航打開/關閉。我終於實現了我目標的90%左右,但Safari和iOS Safari中的歷史記錄實施得非常差,因此請刪除這些瀏覽器的功能。

使用散列法可能會遇到的一些問題是,當您將#與pushstate一起使用時,它實際上不會將新對象推入歷史狀態。它有時似乎把歷史推到堆棧上,你可以使用history.back()來激發一個popstate,但是如果你說用你的hashurl刷新頁面,並且在頁面啓動時做一些檢查hash, t似乎是推向堆棧的新歷史,因此在向後導航時用戶將離開站點而不是關閉模式。

這裏工作,對於除瀏覽器它回落到正常的行爲我的實現是Safari瀏覽器:

http://dtothefp.github.io/hosted_modal_history_sample/ https://github.com/dtothefp/html5history_express_modal_toggle

就像我說我結合使用History.js用的sessionStorage因爲夠煩人,在popstate關閉模式的歷史對象被刪除,這正是我需要它的時候。在所有實施非常差的API中。

我不改變URL,因爲這個項目沒有後端,所以如果我改變URL沒有散列,頁面刷新頁面將不會被發現。另一種實現方式是查詢字符串,它將在推送狀態中使用時正確更新歷史記錄,但最終會成爲不良用戶體驗,因爲如果用戶關閉不使用向後導航的模式(即點擊取消按鈕或單擊關閉)查詢字符串將導致頁面刷新。