2015-01-19 28 views
23

Sử dụng html5 window.history API, tôi có thể kiểm soát điều hướng khá tốt trên ứng dụng web của mình.JS - window.history - Xóa trạng thái

Ứng dụng hiện có hai trạng thái: selectDate (1) và enterDetails (2).

Khi tải ứng dụng, tôi replaceState và thiết lập một listener popState:

history.replaceState({stage:"selectDate",...},...); 
window.onpopstate = function(event) { 
    that.toStage(event.state.stage); 
}; 

Khi một ngày được chọn và ứng dụng chuyển sang giai đoạn 2 Tôi đẩy trạng thái 2 vào stack:

history.pushState({stage:"enterDetails",...},...); 

Trạng thái này được thay thế bất cứ lúc nào chi tiết thay đổi để chúng được lưu trong lịch sử.

Có ba cách để bỏ giai đoạn 2:

  • tiết kiệm (ajax nộp)
  • hủy
  • nút quay lại

Các nút quay lại được xử lý bởi popstate nghe. Nút hủy đẩy giai đoạn 1 để người dùng có thể quay lại chi tiết họ đang nhập vào nút quay lại. Cả hai đều hoạt động tốt.

Nút lưu sẽ hoàn nguyên về giai đoạn 1 và không cho phép người dùng điều hướng quay lại trang chi tiết (vì họ đã gửi). Về cơ bản, bạn nên đặt ngăn xếp lịch sử là length = 1.

Nhưng dường như không có history.delete() hoặc history.merge(). Điều tốt nhất tôi có thể làm là history.replaceState(stage1) để lại ngăn xếp lịch sử là: ["selectDate","selectDate"].

Làm cách nào để loại bỏ một lớp?

Edit:

tưởng của cái gì khác, nhưng nó không hoạt động nữa.

history.back(); //moves history to the correct position 
location.href = "#foo"; // successfully removes ability to go 'forward', 
         // but also adds another layer to the history stack 

Điều này để ngăn xếp lịch sử là ["selectDate","selectDate#foo"].

Vì vậy, thay vào đó, có cách nào để xóa lịch sử 'chuyển tiếp' mà không cần đẩy trạng thái mới không?

Trả lời

34

Bạn có thể đã di chuyển vào lúc này, nhưng ... theo như tôi biết không có cách nào để xóa mục nhập lịch sử (hoặc tiểu bang).

Một tùy chọn tôi đã xem xét là tự xử lý lịch sử trong JavaScript và sử dụng đối tượng window.history làm nhà cung cấp dịch vụ. Về cơ bản, khi trang đầu tiên tải bạn tạo đối tượng lịch sử tùy chỉnh của bạn (chúng tôi sẽ đi với một mảng ở đây, nhưng sử dụng bất cứ điều gì có ý nghĩa cho tình huống của bạn), sau đó làm pushState ban đầu của bạn. Tôi sẽ chuyển đối tượng lịch sử tùy chỉnh của bạn làm đối tượng trạng thái, vì nó có thể có ích nếu bạn cũng cần xử lý người dùng điều hướng khỏi ứng dụng của bạn và quay lại sau.

var myHistory = []; 

function pageLoad() { 
    window.history.pushState(myHistory, "<name>", "<url>"); 

    //Load page data. 
} 

Bây giờ khi bạn di chuyển, bạn thêm vào đối tượng lịch sử của riêng bạn (hoặc không - lịch sử tại là trong tay của bạn!) Và sử dụng replaceState để giữ cho trình duyệt ra khỏi vòng lặp.

function nav_to_details() { 
    myHistory.push("page_im_on_now"); 
    window.history.replaceState(myHistory, "<name>", "<url>"); 

    //Load page data. 
} 

Khi người dùng điều hướng ngược, họ sẽ nhấn trạng thái "cơ sở" (đối tượng trạng thái của bạn sẽ rỗng) và bạn có thể điều hướng theo đối tượng lịch sử tùy chỉnh của mình. Sau đó, bạn thực hiện một pushState khác.

function on_popState() { 
    // Note that some browsers fire popState on initial load, 
    // so you should check your state object and handle things accordingly. 
    // (I did not do that in these examples!) 

    if (myHistory.length > 0) { 
     var pg = myHistory.pop(); 
     window.history.pushState(myHistory, "<name>", "<url>"); 

     //Load page data for "pg". 
    } else { 
     //No "history" - let them exit or keep them in the app. 
    } 
} 

Người dùng sẽ không bao giờ có thể điều hướng về phía trước bằng cách sử dụng nút trình duyệt của họ vì họ luôn ở trên trang mới nhất.

Từ góc nhìn của trình duyệt, mỗi lần họ quay lại "", họ đã ngay lập tức bị đẩy về phía trước một lần nữa.

Từ quan điểm của người dùng, họ có thể điều hướng ngược qua các trang nhưng không chuyển tiếp (về cơ bản mô phỏng mẫu "ngăn xếp trang" của điện thoại thông minh).

Từ góc nhìn của nhà phát triển, bây giờ bạn có mức kiểm soát cao về cách người dùng điều hướng qua ứng dụng của bạn, trong khi vẫn cho phép họ sử dụng các nút điều hướng quen thuộc trên trình duyệt của họ. Bạn có thể thêm/xóa các mục từ bất kỳ đâu trong chuỗi lịch sử như bạn muốn. Nếu bạn sử dụng các đối tượng trong mảng lịch sử của mình, bạn cũng có thể theo dõi thêm thông tin về các trang (như nội dung trường và không có nội dung).

Bạn cũng có thể mở rộng ý tưởng để xử lý điều hướng chuyển tiếp. Bạn sẽ cần 3 trang - một trang xử lý "ngược lại", một trang xử lý "chuyển tiếp" và trang "phần còn lại" ở giữa các trang mà người dùng thường sẽ ở đó. Sau đó bạn sẽ cần phải đi qua lại dọc theo đối tượng lịch sử của bạn thay vì chỉ đơn giản là đẩy/popping các mục.

+0

Xin cảm ơn. Đó là khá thanh lịch hơn so với những gì tôi đã được sử dụng như một workaround. – slicedtoad

+0

Việc cần làm khi người dùng quen với hành vi này, sau đó điều hướng vài lần để xây dựng trạng thái, sau đó điều hướng đến trang web bên ngoài, sau đó điều hướng trở lại và tôi giả sử lịch sử của tất cả điều hướng của ứng dụng hiện đã biến mất và nút quay lại sẽ là cuối cùng trên heap. –

+0

Trạng thái được đẩy bởi history.pushState sẽ khả dụng khi chúng quay lại (cũng nếu chúng đóng hoặc làm mới trình duyệt của chúng). Một số trình duyệt sẽ kích hoạt sự kiện popstate khi tải trang, nhưng một số khác thì không (ví dụ Firefox). Nhưng bạn luôn có thể đọc history.state trực tiếp. Nếu bạn không sử dụng đối tượng history.state, bạn sẽ cần sử dụng một phương tiện khác để duy trì trạng thái của bạn (như localStorage). history.state được tiếp tục tự động như là một phần của lịch sử duyệt web. –

Các vấn đề liên quan