如何偵測瀏覽器後退按鈕事件 - 跨瀏覽器
P粉141911244
P粉141911244 2023-08-23 16:23:49
0
2
640
<p>如何明確偵測使用者是否按下了瀏覽器中的後退按鈕? </p> <p>如何使用 <code>#URL</code> 系統在單頁 Web 應用程式中強制使用頁內後退按鈕? </p> <p>到底為什麼瀏覽器會後退按鈕不會觸發自己的事件! ? </p>
P粉141911244
P粉141911244

全部回覆(2)
P粉662614213

您可以嘗試popstate 事件處理程序,例如:

window.addEventListener('popstate', function(event) {
    // The popstate event is fired each time when the current history entry changes.

    var r = confirm("You pressed a Back button! Are you sure?!");

    if (r == true) {
        // Call Back button programmatically as per user confirmation.
        history.back();
        // Uncomment below line to redirect to the previous page instead.
        // window.location = document.referrer // Note: IE11 is not supporting this.
    } else {
        // Stay on the current page.
        history.pushState(null, null, window.location.pathname);
    }

    history.pushState(null, null, window.location.pathname);

}, false);

注意:為了獲得最佳結果,您應該僅在要實現邏輯的特定頁面上載入此程式碼,以避免任何其他意外問題。

每次目前歷史記錄條目變更(使用者​​導覽至新狀態)時都會觸發 popstate 事件。當使用者點選瀏覽器的後退/前進按鈕或當history.back()history.forward()history.go() 時,就會發生這種情況> 方法以程式設計方式呼叫。

event.state 是事件的屬性,等於歷史狀態物件。

對於 jQuery 語法,將其環繞(在文件準備好後新增偶數偵聽器):

(function($) {
  // Above code here.
})(jQuery);

另請參閱:頁面載入時的 window.onpopstate


另請參閱單頁應用程式和 HTML5 PushState 上的範例頁面:

<script>
// jQuery
$(window).on('popstate', function (e) {
    var state = e.originalEvent.state;
    if (state !== null) {
        //load content with ajax
    }
});

// Vanilla javascript
window.addEventListener('popstate', function (e) {
    var state = e.state;
    if (state !== null) {
        //load content with ajax
    }
});
</script>

這應該與 Chrome 5 、Firefox 4 、IE 10 、Safari 6 、Opera 11.5 及類似版本相容。

P粉949190972

(注意:根據 Sharky 的回饋,我新增了偵測退格鍵的程式碼)

所以,我經常在 SO 上看到這些問題,最近自己也遇到了控制後退按鈕功能的問題。經過幾天的尋找適合我的應用程式的最佳解決方案(帶有哈希導航的單頁)後,我想出了一個簡單的、跨瀏覽器的、無庫的系統來檢測後退按鈕。

大多數人建議使用:

window.onhashchange = function() {
 //blah blah blah
}

但是,當使用者使用更改位置雜湊的頁內元素時,也會呼叫此函數。當使用者點擊並且頁面向後或向前移動時,這不是最佳的使用者體驗。

為了向您提供我的系統的整體輪廓,當使用者在介面中移動時,我將使用先前的雜湊值填充一個陣列。它看起來像這樣:

function updateHistory(curr) {
    window.location.lasthash.push(window.location.hash);
    window.location.hash = curr;
}

非常簡單。我這樣做是為了確保跨瀏覽器支援以及對舊版瀏覽器的支援。只需將新的哈希值傳遞給該函數,它就會為您儲存它,然後更改哈希值(然後將其放入瀏覽器的歷史記錄中)。

我還利用了一個頁內後退按鈕,該按鈕使用 lasthash 陣列在頁面之間移動用戶。它看起來像這樣:

function goBack() {
    window.location.hash = window.location.lasthash[window.location.lasthash.length-1];
    //blah blah blah
    window.location.lasthash.pop();
}

因此,這會將用戶移回到最後一個哈希,並從數組中刪除最後一個哈希(我現在沒有前進按鈕)。

所以。如何偵測使用者是否使用了我的頁內後退按鈕或瀏覽器按鈕?

起初我查看了window.onbeforeunload,但沒有結果——只有當使用者要更改頁面時才會呼叫它。在使用哈希導航的單頁應用程式中不會發生這種情況。

所以,經過更多的挖掘,我看到了嘗試設定標誌變數的建議。在我的例子中,這個問題是我會嘗試設定它,但由於一切都是非同步的,它並不總是針對哈希更改中的 if 語句及時設定。 .onMouseDown 並不總是在 click 中調用,並且將其添加到 onclick 中永遠不會足夠快地觸發它。

從那時起,我開始研究文件視窗之間的差異。我的最終解決方案是使用 document.onmouseover 設定該標誌,並使用 document.onmouseleave 來停用它。

發生的情況是,當使用者的滑鼠位於文件區域內(讀取:渲染的頁面,但不包括瀏覽器框架)時,我的布林值會設定為true。一旦滑鼠離開文件區域,布林值就會翻轉為 false

這樣,我可以將 window.onhashchange 更改為:

window.onhashchange = function() {
    if (window.innerDocClick) {
        window.innerDocClick = false;
    } else {
        if (window.location.hash != '#undefined') {
            goBack();
        } else {
            history.pushState("", document.title, window.location.pathname);
            location.reload();
        }
    }
}

您會注意到 #undefined 的檢查。這是因為如果我的陣列中沒有可用的歷史記錄,它將傳回 undefined。我用它來詢問使用者是否想使用 window.onbeforeunload 事件離開。

因此,簡而言之,對於不一定使用頁內後退按鈕或陣列來儲存歷史記錄的人:

document.onmouseover = function() {
    //User's mouse is inside the page.
    window.innerDocClick = true;
}

document.onmouseleave = function() {
    //User's mouse has left the page.
    window.innerDocClick = false;
}

window.onhashchange = function() {
    if (window.innerDocClick) {
        //Your own in-page mechanism triggered the hash change
    } else {
        //Browser back button was clicked
    }
}

這就是你想要的。一種簡單的三部分方法,用於檢測後退按鈕的使用情況與哈希導航方面的頁內元素的情況。

編輯:

為了確保使用者不會使用退格鍵來觸發後退事件,您還可以包含以下內容(感謝 這個問題):

$(function(){
    /*
     * this swallows backspace keys on any non-input element.
     * stops backspace -> back
     */
    var rx = /INPUT|SELECT|TEXTAREA/i;

    $(document).bind("keydown keypress", function(e){
        if( e.which == 8 ){ // 8 == backspace
            if(!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly ){
                e.preventDefault();
            }
        }
    });
});
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板