ví dụ history.replaceState ()?


126

Có ai có thể đưa ra một ví dụ hoạt động cho history.replaceState không? Đây là những gì w3.org nói:

history . replaceState(data, title [, url ] )

Cập nhật mục hiện tại trong lịch sử phiên để có dữ liệu, tiêu đề cụ thể và, nếu được cung cấp và không có giá trị, URL.

Cập nhật:

Điều này hoạt động hoàn hảo:

history.replaceState( {} , 'foo', '/foo' );

Url đang thay đổi, nhưng tiêu đề không thay đổi. Đó có phải là một lỗi hay tôi đang thiếu một cái gì đó? Đã thử nghiệm trên Chrome mới nhất.


3
Tôi thường không đẩy các thư viện bổ trợ cho các câu hỏi JavaScript, nhưng trong trường hợp này tôi sẽ tạo một ngoại lệ. Các History.js thư viện là một shim nhỏ mà dọn dẹp rất nhiều hành vi sai trái kỳ lạ trong API Lịch sử trên các trình duyệt hiện đại. Nó thậm chí còn cung cấp hỗ trợ tùy chọn cho các phiên bản IE cũ.
nhọn

2
MDN có một bài viết khá hay về Thao tác lịch sử trình duyệt
sachleen

@Pointy history.js hoạt động rất tốt. Tôi đã cập nhật mã trong câu hỏi của tôi. Không có vấn đề gì là tôi không thể quay lại trang trước bằng nút quay lại của trình duyệt
Serjas

3
Theo Mozilla , titletham số này không thực sự được sử dụng.
Tên lửa Hazmat

3
Câu trả lời đầu tiên thực sự không nên là câu trả lời được chấp nhận, đưa ra câu hỏi yêu cầu một replaceStateví dụ và câu trả lời được chấp nhận không phải là một replaceStateví dụ.
CorayThan

Câu trả lời:


68

Quả thực đây là một lỗi, mặc dù đã cố ý trong 2 năm nay. Vấn đề nằm ở một số thông số kỹ thuật không rõ ràng và sự phức tạp khidocument.title và lùi / tiến có liên quan.

Xem tài liệu tham khảo lỗi trên WebkitMozilla . Ngoài ra Opera khi giới thiệu History API cho biết họ không sử dụng tham số tiêu đề và có lẽ vẫn không.

Hiện tại, đối số thứ 2 của PushState và thay thếState - tiêu đề của mục lịch sử - không được sử dụng trong triển khai của Opera, nhưng có thể là một ngày.

Giải pháp tiềm năng

Cách duy nhất tôi thấy là thay đổi thành phần tiêu đề và sử dụng PushState thay thế:

document.getElementsByTagName('title')[0].innerHTML = 'bar';
window.history.pushState( {} , 'bar', '/bar' );

Đối với người dùng jquery .. hãy thử $ ("title"). Html (_title);
suraj jain

3
điều này có thể dẫn đến việc người dùng cần "nhấp đúp" vào nút quay lại tùy thuộc vào cách bạn thực hiện việc này. Một giải pháp đơn giản hơn có thể là tiếp tục sử dụng replaceState()và chỉ cần đặt tiêu đề tài liệu theo cách thủ côngdocument.title = "title"
newshorts

38

Đây là một ví dụ tối thiểu.

console.log( window.location.href );  // whatever your current location href is
window.history.replaceState( {} , 'foo', '/foo' );
console.log( window.location.href );  // oh, hey, it replaced the path with /foo

Có nhiều hơn replaceState()nhưng tôi không biết chính xác những gì bạn muốn làm với nó.


2
url đang thay đổi, nhưng tiêu đề không thay đổi .. đã được thử nghiệm với chrome @trott mới nhất
Serjas

6
@Serjas titleTham số trong replaceState(), theo sự hiểu biết tốt nhất của tôi, bị bỏ qua trong tất cả các trình duyệt.
Trott

10

history.pushStateđẩy trạng thái trang hiện tại lên ngăn xếp lịch sử và thay đổi URL trong thanh địa chỉ. Vì vậy, khi bạn quay trở lại, trạng thái đó (đối tượng bạn đã vượt qua) được trả lại cho bạn.

Hiện tại, đó là tất cả những gì nó làm. Bất kỳ hành động trang nào khác, chẳng hạn như hiển thị trang mới hoặc thay đổi tiêu đề trang, phải được bạn thực hiện.

Thông số W3C mà bạn liên kết chỉ là bản nháp và trình duyệt có thể triển khai theo cách khác. Firefox , ví dụ, bỏ quatitle hoàn toàn tham số.

Đây là một ví dụ đơn giản pushStatemà tôi sử dụng trên trang web của mình.

(function($){
    // Use AJAX to load the page, and change the title
    function loadPage(sel, p){
        $(sel).load(p + ' #content', function(){
            document.title = $('#pageData').data('title');
        });
    }

    // When a link is clicked, use AJAX to load that page
    // but use pushState to change the URL bar
    $(document).on('click', 'a', function(e){
        e.preventDefault();
        history.pushState({page: this.href}, '', this.href);
        loadPage('#frontPage', this.href);
    });

    // This event is triggered when you visit a page in the history
    // like when yu push the "back" button
    $(window).on('popstate', function(e){
        loadPage('#frontPage', location.pathname);
        console.log(e.originalEvent.state);
    });
}(jQuery));

29
Tại sao câu trả lời được chấp nhận giải thích "PushState" thay vì "thay thế"?
Giwrgos Tsopanoglou

1
@GiwrgosTsopanoglou: Tôi đã trả lời điều này một năm trước, vì vậy tôi không chắc tại sao :-P Dù sao, replaceStatethay đổi trạng thái trang hiện tại. Nó cho phép bạn thay đổi đối tượng trạng thái và URL của trạng thái trang hiện tại .
Tên lửa Hazmat

2
Thật kỳ lạ khi tôi đang tìm kiếm thông tin về thay thế và cuối cùng tôi đã đọc về PushState: P
Giwrgos Tsopanoglou

6

nhìn vào ví dụ

window.history.replaceState({
    foo: 'bar'
}, 'Nice URL Title', '/nice_url');

window.onpopstate = function (e) {
    if (typeof e.state == "object" && e.state.foo == "bar") {
        alert("Blah blah blah");
    }
};

window.history.go(-1);

và tìm kiếm location.hash;


2

Đối số thứ hai Tiêu đề không có nghĩa là Tiêu đề của trang - Nó thiên về định nghĩa / thông tin cho trạng thái của trang đó

Nhưng chúng ta vẫn có thể thay đổi tiêu đề bằng cách sử dụng sự kiện onpopstate và truyền tên tiêu đề không phải từ đối số thứ hai, mà là một thuộc tính từ tham số đầu tiên được truyền dưới dạng đối tượng

Tham khảo: http://spoiledmilk.com/blog/html5-changing-the-browser-url-without-refreshing-page/


2

Theo tài liệu Lịch sử MDN
Rõ ràng đã nói rằng đối số thứ hai là cho tương lai được sử dụng không phải bây giờ. Bạn đúng rằng đối số thứ hai là đối phó với tiêu đề trang web nhưng hiện tại nó bị bỏ qua bởi tất cả các trình duyệt chính.

Firefox hiện đang bỏ qua tham số này, mặc dù nó có thể sử dụng nó trong tương lai. Truyền chuỗi rỗng ở đây sẽ an toàn trước các thay đổi trong tương lai của phương thức. Ngoài ra, bạn có thể chuyển một tiêu đề ngắn cho trạng thái mà bạn đang di chuyển.


Đối số thứ hai không không tham khảo các tiêu đề của web-page - doc MDN mà bạn liên kết nói "vượt qua một đoạn ngắn tiêu đề cho tình trạng mà bạn đang di chuyển." . Điều này đồng ý với tài liệu giao diện lịch sử W3C cho biết "Đẩy dữ liệu đã cho vào lịch sử phiên, với tiêu đề đã cho" . Dữ liệu trong cụm từ đó là dữ liệu trạng thái , do đó, một lần nữa tiêu đề đề cập đến trạng thái (dữ liệu).
Stephen P

1

Tôi thực sự muốn trả lời câu trả lời của @ Sev.

Sev nói đúng, có một lỗi bên trong window.history.replaceState

Để khắc phục điều này chỉ cần viết lại hàm tạo để đặt tiêu đề theo cách thủ công.

var replaceState_tmp = window.history.replaceState.constructor;
window.history.replaceState.constructor = function(obj, title, url){
    var title_ = document.getElementsByTagName('title')[0];
    if(title_ != undefined){
        title_.innerHTML = title;
    }else{
        var title__ = document.createElement('title');
        title__.innerHTML = title;
        var head_ = document.getElementsByTagName('head')[0];
        if(head_ != undefined){
            head_.appendChild(title__);
        }else{
            var head__ = document.createElement('head');
            document.documentElement.appendChild(head__);
            head__.appendChild(title__);
        }
    }
    replaceState_tmp(obj,title, url);
}

2
Đừng làm vậy. Ghi đè các chức năng mặc định thực sự là phong cách xấu
René Roth

3
bạn có đề nghị gì khác khi bạn cần sửa lỗi này?
Glenn Plas

@GlennPlas mở PR chống lại repo phản ứng :)
zero_cool

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.