Bạn có thể sử dụng điều hướng băm mà không ảnh hưởng đến lịch sử không?


99

Tôi e rằng điều đó là không thể nhưng có cách nào để thay đổi giá trị băm của URL mà không để lại mục nhập trong lịch sử của trình duyệtkhông cần tải lại không? Hoặc làm tương đương?

Về phần chi tiết cụ thể, tôi đang phát triển một số điều hướng băm cơ bản dọc theo các dòng:

//hash nav -- works with js-tabs
var getHash = window.location.hash;
var hashPref = "tab-";
function useHash(newHash) {
    //set js-tab according to hash
    newHash = newHash.replace('#'+hashPref, '');
    $("#tabs li a[href='"+ newHash +"']").click();
}
function setHash(newHash) {
    //set hash according to js-tab
    window.location.hash = hashPref + newHash;

    //THIS IS WHERE I would like to REPLACE the location.hash
    //without a history entry

}
    // ... a lot of irrelavent tabs js and then....

    //make tabs work
    $("#tabs.js-tabs a").live("click", function() {
        var showMe = $(this).attr("href");
        $(showMe).show();
        setHash(showMe);
        return false;
    });
    //hash nav on ready .. if hash exists, execute
    if ( getHash ){
        useHash(getHash);
    }

Rõ ràng là sử dụng jQuery. Ý tưởng là trong trường hợp cụ thể này 1) khiến người dùng quay lại mọi thay đổi tab có thể 'phá vỡ nút quay lại' một cách hiệu quả bằng cách chất đống các tham chiếu không cần thiết và 2) không giữ lại tab nào họ hiện đang ở nếu họ nhấn làm mới một sự khó chịu.


Tại sao bạn muốn thay đổi hàm băm nếu không muốn theo dõi lịch sử? : |
Ionuț Staicu

9
Bởi vì khi làm mới, tốt nhất là giới thiệu cho người dùng tab mà họ đang ở trên, nhưng vì họ có thể lật qua lật lại giữa các tab, nó sẽ làm rối lịch sử của họ với các mục nhập một cách không cần thiết, khiến nút quay lại thực sự kém hữu ích hơn. Tuy nhiên, đây chỉ là một ví dụ - có thể bất cứ lúc nào bạn cần lưu trạng thái tạm thời nhưng không muốn dựa vào cookie hoặc điền vào tệp tạm thời của người dùng. Khi bạn làm mới, nội dung js giống như bạn đã rời khỏi nó - bạn chưa rời khỏi trang và nó không phải là trang chuyển đến điểm hoặc trang psuedo, vì vậy mục nhập lịch sử chỉ có thể can thiệp vào điều hướng tiêu chuẩn.

Câu trả lời:


94

location.replace("#hash_value_here");hoạt động tốt cho tôi cho đến khi tôi thấy rằng nó không hoạt động trên iOS Chrome. Trong trường hợp đó, hãy sử dụng:

history.replaceState(undefined, undefined, "#hash_value")

history.replaceState () hoạt động giống như history.pushState () ngoại trừ việc ReplaceState () sửa đổi mục nhập lịch sử hiện tại thay vì tạo một mục mới.

Hãy nhớ giữ nguyên #hoặc phần cuối cùng của url sẽ bị thay đổi.


3
Hoàn toàn là cách để đi cho các trình duyệt hiện đại; hãy lưu ý đến việc quản lý lịch sử phiên hỗ trợ một phần có.
Matt

Tôi bối rối không biết làm thế nào để sử dụng điều này. Tôi vẫn nên sử dụng window.location.hash = 'my-hash';tiếp theo history.replaceState(undefined, undefined, "#my-hash")?
Bram Vanroy

2
@BramVanroy Không, sử dụng cái sau là đủ.
Lucia

2
Trừ khi bạn sử dụng: bộ chọn mục tiêu ... thì các chức năng lịch sử sẽ vô dụng, vì phần đó của thông số kỹ thuật (tương tác css với hoạt động lịch sử) dường như không được xác định hiện tại và kiểu không được thay thế lịch sử bởi hầu hết / tất cả các trình duyệt.
morphles

@Luxiyalu, Khác biệt như thế nào history.replaceStatevới location.replace?
Pacerier

99
location.replace("#hash_value_here"); 

Ở trên dường như làm những gì bạn đang theo đuổi.


4
Đây là nó. Và nếu bạn có phân đoạn tiểu, location.replace (window.location + "#hash") sẽ giữ nguyên chúng.
tedders

7
Chấp nhận phương pháp này, rõ ràng hơn nhiều, ước gì nó được đánh dấu là câu trả lời chính xác.
joeellis

14
window.location.replace(('' + window.location).split('#')[0] + '#' + hash);chỉ cập nhật mã băm
johnstorm

1
Tôi đang thử nghiệm tính năng này trong Chrome 30 trong Windows 8, nếu tôi truy cập Lịch sử Chrome và chọn "Thêm từ trang web này" trong url thử nghiệm của mình, tôi có thể thấy tất cả các hàm băm đã được thêm bằng phương pháp này.
Alex Vang

1
Hãy lưu ý rằng location.replace ('# hash_value_here') chỉ thay đổi phân đoạn băm chứ không phải đường dẫn, vì vậy nó không kích hoạt tải trang .... Ngoại trừ khi tài liệu chứa thẻ cơ sở: <base href ="http://example.com/" /> Nếu tài liệu có chứa thẻ cơ sở , thì khi bạn sử dụng phương thức thay thế chỉ với một phần đầu, "#hash_value_here"nó thực sự sẽ giống như thể bạn đã nói `location.replace (' example.com/#hash_value_here' ). Điều này có vẻ rõ ràng khi bạn đọc nó ở đây, nhưng là lỗi khi bạn đang ở trên một trang có một đoạn đường dẫn và không nhận ra rằng cơ sở đã được thiết lập.
Tyler Kasten

6

Chỉnh sửa: Đã một vài năm nay và các trình duyệt đã phát triển.

Câu trả lời của @ Luxiyalu là con đường để đi

- Câu trả lời cũ -

Tôi cũng nghĩ rằng điều đó là không thể (tại thời điểm này). Nhưng tại sao bạn cần thay đổi giá trị băm nếu bạn không sử dụng nó?

Tôi tin rằng lý do chính tại sao chúng tôi sử dụng giá trị băm với tư cách là lập trình viên là để người dùng đánh dấu trang của chúng tôi hoặc để lưu trạng thái trong lịch sử trình duyệt. Nếu bạn không muốn làm bất kỳ điều này, thì chỉ cần lưu trạng thái trong một biến và làm việc từ đó.

Tôi nghĩ rằng lý do để sử dụng hàm băm là để làm việc với một giá trị nằm ngoài tầm kiểm soát của chúng tôi. Nếu bạn không cần nó, thì điều đó có nghĩa là bạn có mọi thứ trong tầm kiểm soát của mình, vì vậy chỉ cần lưu trữ trạng thái trong một biến và làm việc với nó. (Tôi thích lặp lại chính mình)

Tôi hy vọng điều này sẽ giúp bạn ra ngoài. Có thể có một giải pháp dễ dàng hơn cho vấn đề của bạn.

CẬP NHẬT: Còn cái này thì sao:

  1. Thiết lập băm đầu tiên và đảm bảo rằng nó được lưu trong lịch sử trình duyệt.
  2. Khi một tab mới được chọn, hãy làm window.history.back(1), điều đó sẽ làm cho lịch sử quay trở lại từ lần băm init đầu tiên của bạn.
  3. Bây giờ bạn đặt hàm băm mới, do đó việc phân chia tab sẽ chỉ tạo một mục nhập trong lịch sử.

Có thể bạn sẽ phải sử dụng một số cờ để biết liệu mục nhập hiện tại có thể bị "xóa" bằng cách quay lại hay bạn chỉ bỏ qua bước đầu tiên. Và để đảm bảo rằng phương thức tải của bạn cho "băm" không thực thi, khi bạn buộc history.back.


Rất có thể có điều gì đó cơ bản mà tôi đang thiếu (kiệt sức là một lý do tuyệt vời, tôi sẽ tiếp tục điều đó) nhưng bạn đang nói rằng tôi có thể đặt một biến sẽ giữ lại giá trị đã thay đổi của nó khi tải lại? Ngoài ra với một cái bánh quy? (Cookie có vẻ quá mức cần thiết, bằng cách nào đó ..) Có lẽ đó là những gì không rõ ràng. Tôi sẽ sử dụng giá trị băm - đặc biệt là khi tải lại. Cảm ơn vì đã phản hồi!

Để làm rõ sự làm rõ của tôi: nếu người dùng nhấn tải lại. Đó là những gì hàm băm dành cho. Tôi vẫn đang cố gắng tránh tải lại khi chúng sử dụng bình thường (thay đổi / nhấp vào tab).

Ok, vì vậy bạn sẽ sử dụng một số giá trị cho thông tin sau khi tải lại. Rất tiếc, giá trị băm sẽ được chọn bởi lịch sử của một số trình duyệt. Xin lỗi phải nói điều này, nhưng theo kinh nghiệm của tôi, cookie là lựa chọn tốt nhất của bạn. Nếu bạn muốn thứ gì đó mà lịch sử trình duyệt không phát hiện ra, nhưng để giữ lại sau khi tải lại, thật không may, cookie. Nếu người dùng đang nhấp vào một liên kết, thì bạn có thể thiết lập liên kết thành một truy vấn ( ?mystate=greatness), mặc dù nó không cần phải là ajax, bạn có thể lưu thông tin cho javascript để đọc khi khởi tạo yêu cầu.
guzart

Vâng, băm là để lưu thông tin của người dùng sau khi chạm tải lại, nhưng vấn đề cho bạn tình, đó là một số trình duyệt sẽ lưu những thay đổi đó trong lịch sử, đó chỉ là cách họ làm việc ... :(
guzart

Đúng, nghĩ rằng bạn đúng. À tốt. (Rất thích để có được chứng minh sai bằng một số phương pháp khác hay một cái gì đó.)

-1

Bạn luôn có thể tạo trình xử lý sự kiện để bắt các sự kiện nhấp chuột trên siêu liên kết và trong hàm gọi lại, hãy đặt e.preventDefault (), điều này sẽ ngăn trình duyệt chèn nó vào lịch sử.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.