Làm cách nào để xóa hàm băm khỏi window.location (URL) bằng JavaScript mà không cần làm mới trang?


331

Tôi có URL như : http://example.com#something, làm cách nào để xóa trang #somethingmà không khiến trang bị làm mới?

Tôi đã thử giải pháp sau:

window.location.hash = '';

Tuy nhiên, điều này không xóa biểu tượng băm #khỏi URL.


3
Bạn có thực sự muốn làm điều này? Nó sẽ gây ra làm mới trang.
seth

9
Có thể làm mà không cần làm mới trang?
Tom Lehman

1
có thể Thư viện lịch sử AJAX đối phó với nó. Nhưng nó không dễ dàng và nó phải được thực hiện khác nhau cho hầu hết mọi trình duyệt. Không phải cái gì bạn muốn nhận được vào.
Gabriel Hurley

Có bất kỳ sự can thiệp nào với việc để lại một "#" phía sau ngoài một hình ảnh không?
dùng29660

Câu trả lời:


210

Câu hỏi ban đầu:

window.location.href.substr(0, window.location.href.indexOf('#'))

hoặc là

window.location.href.split('#')[0]

cả hai sẽ trả về URL mà không cần băm hoặc bất cứ điều gì sau nó.

Liên quan đến chỉnh sửa của bạn:

Mọi thay đổi window.locationsẽ kích hoạt làm mới trang. Bạn có thể thay đổi window.location.hashmà không kích hoạt làm mới (mặc dù cửa sổ sẽ nhảy nếu hàm băm của bạn khớp với id trên trang), nhưng bạn không thể thoát khỏi dấu băm. Hãy lựa chọn cái nào tệ hơn ...

TRẢ LỜI TUYỆT VỜI NHẤT

Câu trả lời đúng về cách thực hiện mà không phải hy sinh (tải lại đầy đủ hoặc để lại dấu băm ở đó) ở đây . Để lại câu trả lời này ở đây mặc dù liên quan đến việc là bản gốc vào năm 2009 trong khi câu trả lời đúng sử dụng API trình duyệt mới đã được đưa ra 1,5 năm sau đó.


22
Điều này hoàn toàn sai, bạn có thể thay đổi window.location.hash và nó sẽ không kích hoạt làm mới.
Evgeny

61
@Evgeny - Đó là những gì câu trả lời của tôi nói. Tôi nói rõ ràng rằng việc thay đổi window.location.hash sẽ không kích hoạt làm mới. "Bạn có thể thay đổi window.location.hash mà không kích hoạt làm mới (mặc dù cửa sổ sẽ nhảy nếu hàm băm của bạn khớp với id trên trang)".
Gabriel Hurley

3
Không tải lại trang - đó là trong câu hỏi. Đây không phải là câu trả lời vì nó yêu cầu / buộc tải lại trang!
Ed_

10
cũng nghĩ rằng nó không nên là ✓answer
abernier

4
Đây không phải là một câu trả lời cho câu hỏi OP.
Bryce

585

Giải quyết vấn đề này là nhiều hơn trong tầm tay ngày nay. Các HTML5 History API cho phép chúng ta thao tác thanh địa chỉ để hiển thị bất kỳ URL trong lĩnh vực hiện tại.

function removeHash () { 
    history.pushState("", document.title, window.location.pathname
                                                       + window.location.search);
}

Bản demo hoạt động: http://jsfiddle.net/AndyE/ycmPt/show/

Điều này hoạt động trong Chrome 9, Firefox 4, Safari 5, Opera 11.50 trong IE 10. Đối với các trình duyệt không được hỗ trợ, bạn luôn có thể viết một tập lệnh xuống cấp duyên dáng sử dụng nó khi có sẵn:

function removeHash () { 
    var scrollV, scrollH, loc = window.location;
    if ("pushState" in history)
        history.pushState("", document.title, loc.pathname + loc.search);
    else {
        // Prevent scrolling by storing the page's current scroll offset
        scrollV = document.body.scrollTop;
        scrollH = document.body.scrollLeft;

        loc.hash = "";

        // Restore the scroll offset, should be flicker free
        document.body.scrollTop = scrollV;
        document.body.scrollLeft = scrollH;
    }
}

Vì vậy, bạn có thể thoát khỏi biểu tượng băm, chỉ trong tất cả các trình duyệt - chưa.

Lưu ý: nếu bạn muốn thay thế trang hiện tại trong lịch sử trình duyệt, hãy sử dụng replaceState()thay vì pushState().


9
Sử dụng dòng này để đảm bảo bạn không bị mất chuỗi truy vấn: history.pushState ("", document.title, window.location.pathname + window.location.search);
Phil Kulak

6
@Phil: cảm ơn bạn đã chỉ ra rằng, tôi đã cập nhật câu trả lời tương ứng. Tôi đã quá quen với việc sử dụng các URL đẹp.
Andy E

1
Đối với các phiên bản IE cũ hơn, có vẻ như bạn cần sử dụng document.documentEuity thay vì document.body. Xem câu trả lời này stackoverflow.com/a/2717272/359048
jasonmcclurg

29
Tôi đề nghị sử dụng thay thếState thay vì PushState, để không tạo thêm một mục trong lịch sử trình duyệt.
Nico

1
@santiagoarizti: bạn nói đúng, tôi cũng đi đến kết luận tương tự. Tôi đã không kiểm tra đúng mã tôi đã viết (7 năm trước!) Và đã bỏ lỡ rằng tôi cũng đang chuyển trạng thái của nút khi xóa hàm băm. Vì bạn đang thay đổi băm thủ công, bạn luôn có thể tự kích hoạt sự kiện, tôi cho rằng.
Andy E

85

(Quá nhiều câu trả lời là dư thừa và lỗi thời.) Giải pháp tốt nhất hiện nay là:

history.replaceState(null, null, ' ');

5
sử dụng history.pushState(null, null, ' ')thay thế nếu bạn muốn bảo tồn lịch sử.
nichoman

9
Nó có thể hữu ích để giải thích những gì vượt qua nullcho statetitlecác tham số cuối cùng làm.
V. Rubinetti

Một vấn đề với điều này và phần còn lại là nó không kích hoạt onhashchange, mặc dù bây giờ hàm băm trống rỗng khi không có trước đó.
Curtis

1
Trong TypeScript, null không được phép cho tham số thứ hai vì lệnh lấy một chuỗi. Mozilla khuyến nghị chuỗi rỗng.
Curtis

41

Đơn giản và thanh lịch:

history.replaceState({}, document.title, ".");  // replace / with . to keep url

3
sử dụng dấu chấm thay vì dấu gạch chéo nếu bạn muốn ở trong cùng thư mục
vahanpwns

1
Vui lòng cập nhật câu trả lời liên quan đến ghi chú @vahanpwns, để sử dụng .thay vì /. Sử dụng /thay đổi url đến đường dẫn gốc.
Isaac Gregson

5
Cảm ơn câu trả lời này, tôi đã sửa đổi history.replaceState({}, document.title, location.href.substr(0, location.href.length-location.hash.length));cho trường hợp sử dụng của tôi.
Scott Jungwirth

5
Điều này không bảo tồn truy vấn url.
Vladislav Kostenko

2
Trường hợp sử dụng của tôi cũng là để thay thế cho việc đẩy, nhưng điều này có ý nghĩa hơn với tôi:history.replaceState(null, document.title, location.pathname + location.search);
MDMower

16

Để xóa hàm băm, bạn có thể thử sử dụng chức năng này

function remove_hash_from_url()
{
    var uri = window.location.toString();
    if (uri.indexOf("#") > 0) {
        var clean_uri = uri.substring(0, uri.indexOf("#"));
        window.history.replaceState({}, document.title, clean_uri);
    }
}

13

Điều này sẽ loại bỏ băm trailing là tốt. ví dụ: http://test.com/123#abc -> http://test.com/123

if(window.history.pushState) {
    window.history.pushState('', '/', window.location.pathname)
} else {
    window.location.hash = '';
}

Thao tác này sẽ xóa mọi tham số truy vấn có trong URL :(
kevgathuku

1
@kevgathuku bạn có thể thêm chúng trở lại với location.search, ví dụ: `window.history.pushState ('', '/', window.location.pathname + window.location.search)`
Chris Gunawardena

6

Làm thế nào về sau đây?

window.location.hash=' '

Xin lưu ý rằng đang đặt băm thành một khoảng trắng và không phải là một chuỗi trống.


Đặt băm thành một neo không hợp lệ cũng không gây ra làm mới. Nhu la,

window.location.hash='invalidtag'

Nhưng, tôi thấy giải pháp trên là sai lệch. Điều này dường như chỉ ra rằng có một mỏ neo trên vị trí nhất định với tên đã cho mặc dù không có cái nào. Đồng thời, việc sử dụng một chuỗi trống khiến trang di chuyển lên đầu có thể không được chấp nhận. Sử dụng một khoảng trắng cũng đảm bảo rằng bất cứ khi nào URL được sao chép và đánh dấu và truy cập lại, trang thường sẽ ở trên cùng và không gian sẽ bị bỏ qua.

Và, này, đây là câu trả lời đầu tiên của tôi trên StackOverflow. Hy vọng ai đó thấy nó hữu ích và nó phù hợp với các tiêu chuẩn cộng đồng.


7
Đặt băm thành khoảng trắng vẫn giữ # ở cuối URL, tôi nghĩ mục tiêu là loại bỏ nó hoàn toàn.
mahemoff

1
Nó theo dõi một hàm băm ở cuối URL. Câu hỏi là làm thế nào để loại bỏ điều đó.
Gurmeet Singh

Có, làm thế nào chúng ta có thể loại bỏ # cũng như với chuỗi băm.
Bhavin Thummar

6

Bạn có thể làm như dưới đây:

history.replaceState({}, document.title, window.location.href.split('#')[0]);


1
Câu trả lời được gắn dấu sao không có tác dụng với tôi trong cả hai trường hợp, nhưng câu trả lời này thì có. Cảm ơn!
Dev

5
const url = new URL(window.location);
url.hash = '';
history.replaceState(null, document.title, url);

2
Mặc dù mã này có thể trả lời câu hỏi, cung cấp ngữ cảnh bổ sung về lý do và / hoặc cách mã này trả lời câu hỏi cải thiện giá trị lâu dài của nó.
rollstuhlfahrer

3
<script type="text/javascript">
var uri = window.location.toString();
if (uri.indexOf("?") > 0) {
    var clean_uri = uri.substring(0, uri.indexOf("?"));
    window.history.replaceState({}, document.title, clean_uri);
}
</script>

đặt mã này vào phần đầu


3
function removeLocationHash(){
    var noHashURL = window.location.href.replace(/#.*$/, '');
    window.history.replaceState('', document.title, noHashURL) 
}

window.addEventListener("load", function(){
    removeLocationHash();
});

2

Tôi nghĩ rằng, nó sẽ an toàn hơn

if (window.history) {
    window.history.pushState('', document.title, window.location.href.replace(window.location.hash, ''));
} else {
    window.location.hash = '';
}

0

Hãy thử như sau:

window.history.back(1);

23
Điều này không trả lời câu hỏi nếu người dùng đã truy cập trực tiếp vào URL bao gồm cả hàm băm.
nickb

Thủ thuật này rất hữu ích khi bạn chỉ muốn tạo một liên kết đến trang trước, nhưng liên kết bị ẩn trong một loạt các tệp js.
Hợp lệ

Chính xác những gì tôi đang tìm kiếm. Điều này hoạt động hoàn hảo để xóa một hashtag vừa được tạo bởi ứng dụng web của tôi để tiêu thụ một giá trị được trả về bởi hàm javasript.
dùng278859

0

Đây là một giải pháp khác để thay đổi vị trí bằng cách sử dụng href và xóa hàm băm mà không cần cuộn.

Giải pháp kỳ diệu được giải thích ở đây . Thông số kỹ thuật ở đây .

const hash = window.location.hash;
history.scrollRestoration = 'manual';
window.location.href = hash;    
history.pushState('', document.title, window.location.pathname);

LƯU Ý: API được đề xuất hiện là một phần của Tiêu chuẩn sống WhatWG HTML


0
  $(window).on('hashchange', function (e) {
        history.replaceState("", document.title, e.originalEvent.oldURL);
    });

-1

Bạn có thể thay thế hàm băm bằng null

var urlWithoutHash = document.location.href.replace(location.hash , "" );

1
Câu hỏi hỏi "không khiến trang bị làm mới", nhưng phương pháp này không làm mới trang. Bạn nên lưu ý thực tế này trong câu trả lời của bạn, vì vậy tất cả chúng ta không phải lãng phí thời gian để tìm hiểu trước rằng bạn đang trả lời một câu hỏi khác với câu hỏi mà chúng ta thực sự đang cố gắng trả lời ở đây.
Vladimir Kornea

Nó không làm mới trang.
Ciprian
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.