Como remover o hash do window.location (URL) com JavaScript sem atualização da página?

332

Tenho URL como:, http://example.com#somethingcomo faço para remover #something, sem fazer com que a página seja atualizada?

Tentei a seguinte solução:

window.location.hash = '';

No entanto, isso não remove o símbolo de hash #do URL.

Tom Lehman
fonte
3
Você realmente quer fazer isso? Isso causará uma atualização da página.
Seth
9
É possível fazer sem uma atualização de página?
9788 Tom Lehman
1
Ele é possível. As bibliotecas de história do AJAX lidam com isso. Mas não é fácil e deve ser feito de maneira diferente para quase todos os navegadores. Não é algo que você queira entrar.
Gabriel Hurley
Existe alguma concordância em deixar um "#" para trás que não seja visual?
user29660
Possível duplicado de modificar o URL sem recarregar a página
PayteR

Respostas:

210

Questão inicial:

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

ou

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

ambos retornarão o URL sem o hash ou qualquer coisa depois dele.

Com relação à sua edição:

Qualquer alteração em window.locationirá acionar uma atualização da página. Você pode alterar window.location.hashsem acionar a atualização (embora a janela salte se o seu hash corresponder a um ID na página), mas você não poderá se livrar do sinal de hash. Faça a sua escolha para o que é pior ...

RESPOSTA MAIS ATUALIZADA

A resposta certa sobre como fazê-lo sem sacrificar (recarregar completamente ou deixar o sinal de hash lá) está aqui embaixo . Deixando essa resposta aqui, porém, em relação a ser a original em 2009, a correta que utiliza novas APIs de navegador foi dada 1,5 anos depois.

Gabriel Hurley
fonte
22
Isso está totalmente errado, você pode alterar window.location.hash e não acionará uma atualização.
Evgeny
61
@ Evgeny - Isso é o que minha resposta diz. Digo explicitamente que a alteração de window.location.hash não acionará uma atualização. "Você pode alterar window.location.hash sem ativar a atualização (embora a janela salte se o seu hash corresponder a um ID na página)".
Gabriel Hurley
3
Nenhuma página recarregada - isso está em questão. Esta não é a resposta, pois requer / força o recarregamento de uma página!
Ed_
10
também acho que não deve ser o ✓answer
abernier
4
Esta não é uma resposta para a pergunta do OP.
Bryce
586

A solução desse problema está muito mais ao alcance hoje em dia. A API de histórico do HTML5 nos permite manipular a barra de localização para exibir qualquer URL no domínio atual.

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

Demonstração de trabalho: http://jsfiddle.net/AndyE/ycmPt/show/

Isso funciona no Chrome 9, Firefox 4, Safari 5, Opera 11.50 e no IE 10. Para navegadores não suportados, você sempre pode escrever um script degradante que o utilize sempre que disponível:

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;
    }
}

Assim, você pode se livrar do símbolo de hash, mas não em todos os navegadores - ainda.

Nota: se você deseja substituir a página atual no histórico do navegador, use em replaceState()vez de pushState().

Andy E
fonte
9
Use esta linha para garantir que você não perca a string de consulta: history.pushState ("", document.title, window.location.pathname + window.location.search);
Phil Kulak
6
@ Phil: obrigado por apontar isso, eu atualizei a resposta em conformidade. Estou muito acostumado a usar URLs bonitas.
Andy E
1
Para versões mais antigas do IE, parece que você precisa usar document.documentElement em vez de document.body. Veja esta resposta stackoverflow.com/a/2717272/359048
jasonmcclurg
29
Sugiro o uso de replaceState em vez de pushState, para não criar uma entrada extra no histórico do navegador.
Nico #
1
@santiagoarizti: você está certo, cheguei à mesma conclusão. Não inspecionei o código que escrevi (há 7 anos!) Corretamente e senti falta de que também estava alternando o estado do botão ao remover o hash. Como você está alterando o hash manualmente, sempre é possível disparar o evento, suponho.
Andy E
85

(Muitas respostas são redundantes e desatualizadas.) A melhor solução agora é a seguinte:

history.replaceState(null, null, ' ');
Pacerier
fonte
5
use history.pushState(null, null, ' ')se você quiser preservar o histórico.
Nichijou
9
Pode ser útil explicar o que a passagem nullpelos parâmetros statee titlefaz.
V. Rubinetti
Um problema com isso, e o resto, é que ele não aciona uma alteração de shh, mesmo que o hash esteja vazio agora quando não estava antes.
Curtis
1
No TypeScript, nulo não é permitido para o segundo parâmetro porque o comando usa uma sequência. A Mozilla recomenda uma string vazia.
Curtis
41

Simples e elegante:

history.replaceState({}, document.title, ".");  // replace / with . to keep url
cprcrack
fonte
3
usar um ponto em vez de uma barra, se você quiser ficar no mesmo diretório
vahanpwns
1
Atualize a resposta no que diz respeito à nota @vahanpwns, para usar em .vez de /. Usar /altera o URL para o caminho raiz.
Isaac Gregson
5
Obrigado por esta resposta, modifiquei para history.replaceState({}, document.title, location.href.substr(0, location.href.length-location.hash.length));para o meu caso de uso.
10135 Scott Scorsett-
5
Isso não preserva a consulta de URL.
Vladislav Kostenko
2
Meu caso de uso também foi substituir em vez de push, mas isso faz mais sentido para mim:history.replaceState(null, document.title, location.pathname + location.search);
MDMower
16

Para remover o hash, você pode tentar usar esta função

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);
    }
}
Rahul Gupta
fonte
13

Isso removerá o hash à direita também. por exemplo: http://test.com/123#abc -> http://test.com/123

if(window.history.pushState) {
    window.history.pushState('', '/', window.location.pathname)
} else {
    window.location.hash = '';
}
Chris Gunawardena
fonte
Isso remove qualquer consulta params presente no URL :(
kevgathuku
1
@kevgathuku você pode adicioná-los de volta com location.search, por exemplo: `window.history.pushState ( '', '/', window.location.pathname + window.location.search)`
Chris Gunawardena
6

Que tal o seguinte?

window.location.hash=' '

Observe que estou configurando o hash para um espaço único e não para uma string vazia.


Definir o hash como uma âncora inválida também não causa atualização. Tal como,

window.location.hash='invalidtag'

Mas, acho a solução acima enganosa. Isso parece indicar que há uma âncora na posição fornecida com o nome dado, embora não exista. Ao mesmo tempo, o uso de uma string vazia faz com que a página seja movida para o topo, o que pode ser inaceitável às vezes. O uso de um espaço também garante que sempre que a URL for copiada, marcada e visitada novamente, a página geralmente estará na parte superior e o espaço será ignorado.

E, ei, esta é minha primeira resposta no StackOverflow. Espero que alguém ache útil e corresponda aos padrões da comunidade.

Nibras Reeza
fonte
7
Definir o hash como espaço em branco ainda mantém o # no final da URL, acho que o objetivo é removê-lo completamente.
Mahemoff # 4/16
1
Ele rastreia um hash no final do URL. A questão é como remover isso.
Gurmeet Singh
Sim, como podemos remover # também com a string hash.
Bhavin Thummar 29/05/19
6

Você pode fazê-lo como abaixo:

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

METALHEAD
fonte
1
A resposta estrelada não funcionou para mim em ambos os casos, mas esta funcionou. Obrigado!
Dev
5
const url = new URL(window.location);
url.hash = '';
history.replaceState(null, document.title, url);
Casey
fonte
2
Embora esse código possa responder à pergunta, fornecer um contexto adicional sobre por que e / ou como esse código responde à pergunta melhora seu valor a longo prazo.
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>

coloque esse código na seção principal

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

window.addEventListener("load", function(){
    removeLocationHash();
});
Vimal Kumar
fonte
2

Eu acho que seria mais seguro

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

Tente o seguinte:

window.history.back(1);
Vishal Sharma
fonte
23
Isso não responde à pergunta se o usuário veio diretamente ao URL, incluindo o hash.
nickb
Esse truque é muito útil quando você deseja criar um link para a página anterior, mas o link está oculto em vários arquivos js.
validFrom
Exatamente o que eu estava procurando. Isso funciona perfeitamente para remover uma hashtag recém-criada pelo meu aplicativo da web para consumir um valor retornado por uma função javasript.
user278859
0

Aqui está outra solução para alterar o local usando href e limpar o hash sem rolar.

A solução mágica é explicada aqui . Especificações aqui .

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

NOTA: A API proposta agora faz parte do WhatWG HTML Living Standard

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

Você pode substituir o hash por nulo

var urlWithoutHash = document.location.href.replace(location.hash , "" );
Devang Bhagdev
fonte
1
A pergunta é feita "sem fazer com que a página seja atualizada", mas esse método atualiza a página. Você deve observar esse fato na sua resposta, para que nem todos tenhamos que perder tempo descobrindo em primeira mão que você está respondendo a uma pergunta diferente daquela que realmente estamos tentando obter aqui.
Vladimir Kornea
Não atualiza a página.
Ciprian