salto em âncora usando javascript

129

Eu tenho uma pergunta que será encontrada com muita frequência. O problema é que em nenhum lugar pode ser encontrada uma solução explícita.

Eu tenho dois problemas com âncoras.

O objetivo principal deve ser obter um URL limpo e agradável sem hashes enquanto estiver usando âncoras para pular em uma página.

Portanto, a estrutura das âncoras é:

<ul>
    <li><a href="#one">One</a></li>
    <li><a href="#two">Two</a></li>
    <li><a href="#three">Three</a></li>
</ul>

<div class="wrap">
    <a name="one">text 1</a>
    <a name="two">text 2</a>
    <a name="three" class="box">text 3</a>
</div>

Ok, se você clicar em um dos links, o URL mudará automaticamente para

www.domain.com/page#1

No final, isso deve ser apenas:

www.domínio.com/página

Por enquanto, tudo bem. Agora, a segunda coisa é que, quando você pesquisar na Internet esse problema, encontrará javascriptuma solução.

Eu encontrei esta função:

function jumpto(anchor){
    window.location.href = "#"+anchor;
}

e chamando essa função com:

<a onclick="jumpto('one');">One</a>

como será o mesmo de antes. Ele adicionará o hash ao URL. Eu também adicionei

<a onclick="jumpto('one'); return false;">

sem sucesso. Então, se houver alguém que possa me dizer como resolver isso, eu realmente aprecio.

Muito obrigado.

bonny
fonte
Não tenho certeza, mas você pode tentar escrever manualmente na propriedade hash após o salto. Por exemplo, defina um tempo limite no manipulador onclick que define window.location.hash=''.
Jeff
Você quer dizer que não deseja exibir o # no URL ao pular para outra seção na mesma página?
Roger Ng
2
Nesse caso, você terá que manipular o scrollTop da janela, normalmente por window.scrollToou pelo auxiliar jQuery correspondente: stackoverflow.com/questions/6677035/jquery-scroll-to-element ou stackoverflow.com/questions/500336/…
Frank van Puffelen
@ Jeff - Se você location.hash='', os #restos lá.
Derek朕會功夫
Não faça isso, por favor. Os hashes são bons ao salvar a página nos seus favoritos.
Marco Sulla 12/01

Respostas:

204

Você pode obter a coordenada do elemento de destino e definir a posição de rolagem para ele. Mas isso é tão complicado.

Aqui está uma maneira mais preguiçosa de fazer isso:

function jump(h){
    var url = location.href;               //Save down the URL without hash.
    location.href = "#"+h;                 //Go to the target element.
    history.replaceState(null,null,url);   //Don't like hashes. Changing it back.
}

Isso usa replaceStatepara manipular o URL. Se você também deseja suporte para o IE , precisará fazê-lo da maneira mais complicada :

function jump(h){
    var top = document.getElementById(h).offsetTop; //Getting Y of target element
    window.scrollTo(0, top);                        //Go there directly or some transition
}​

Demo: http://jsfiddle.net/DerekL/rEpPA/
Outro com transição: http://jsfiddle.net/DerekL/x3edvp4t/

Você também pode usar .scrollIntoView:

document.getElementById(h).scrollIntoView();   //Even IE6 supports this

(Bem, eu menti. Não é nada complicado.)

Derek 朕 會 功夫
fonte
1
Ratos !! O link está quebrado :-( Eu pensei que JS Fiddles ficado lá para sempre
MAWG diz Reintegrar Monica
1
Aparentemente, eles removeram a capacidade de usar o add /showno final do URL.
Derek朕會功夫
11
"Até o IE6 suporta isso" é o melhor comentário que eu já vi.
21415 Josh
3
@Black Não existe um elemento "jQuery". Se você deseja obter o primeiro elemento da sua consulta, faça $(mySelector)[0].scrollIntoView().
Derek朕會功夫
4
1+ para scrollIntoView. 1- por mencionar por último.
Yay295
12

Eu acho que é uma solução muito mais simples:

window.location = (""+window.location).replace(/#[A-Za-z0-9_]*$/,'')+"#myAnchor"

Esse método não recarrega o site e define o foco nas âncoras necessárias para o leitor de tela.

Adam111p
fonte
E o que raramente funciona no IE, isso funciona em todos os IE;)
Adam111p
5
Acabei comwindow.location = window.location.origin + window.location.pathname + '#hash';
Alex
Isso recarregou a página para mim. A resposta aceita acabou funcionando, porém, eu gostaria que fosse mais curta.
precisa saber é o seguinte
3

Representante insuficiente para um comentário.

O método baseado em getElementById () na resposta selecionada não funcionará se a âncora tiver namemas nãoid definida, definida (o que não é recomendado, mas acontece na natureza).

Algo a ter em mente se você não tiver controle da marcação do documento (por exemplo, extensão da web).

O locationmétodo baseado na resposta selecionada também pode ser simplificado com location.replace:

function jump(hash) { location.replace("#" + hash) }
cmc
fonte
1

Porque quando você faz

window.location.href = "#"+anchor;

Você carrega uma nova página, pode fazer:

<a href="#" onclick="jumpTo('one');">One</a>
<a href="#" id="one"></a>

<script>

    function getPosition(element){
        var e = document.getElementById(element);
        var left = 0;
        var top = 0;

        do{
            left += e.offsetLeft;
            top += e.offsetTop;
        }while(e = e.offsetParent);

        return [left, top];
    }

    function jumpTo(id){    
        window.scrollTo(getPosition(id));
    }

</script>
Jonathan Vukovich-Tribouharet
fonte
3
Não acho que adicionar hashes a torne uma nova página.
Derek朕會功夫
5
Não recarrega a página.
Derek朕會功夫
Você está certo, não recarrega a página. Eu tento no console com chrome e o favicon é recarregado.
Jonathan Vukovich-Tribouharet
No Firefox mais recente, as alterações de hash parecem forçar uma recarga para os iFrames (no atributo src). Eu consideraria isso um bug do navegador, mas algo para estar ciente.
Beejor
1

Eu tenho um botão para avisar que, ao clicar, ele abre a caixa de diálogo de exibição e, em seguida, posso escrever o que quero pesquisar e ele vai para esse local na página. Ele usa javascript para responder ao cabeçalho.

No arquivo .html eu tenho:

<button onclick="myFunction()">Load Prompt</button>
<span id="test100"><h4>Hello</h4></span>

No arquivo .js eu tenho

function myFunction() {
    var input = prompt("list or new or quit");

    while(input !== "quit") {
        if(input ==="test100") {
            window.location.hash = 'test100';
            return;
// else if(input.indexOf("test100") >= 0) {
//   window.location.hash = 'test100';
//   return;
// }
        }
    }
}

Quando escrevo test100 no prompt, ele irá para onde coloquei span id = "test100" no arquivo html.

Eu uso o Google Chrome.

Nota: Essa ideia vem do link na mesma página usando

<a href="#test100">Test link</a>

qual clique enviará para a âncora. Para que ele funcione várias vezes, a partir da experiência precisa recarregar a página.

O crédito para as pessoas no stackoverflow (e possivelmente na stackexchange também) não se lembra de como reuni todos os pedaços. ☺

S.Doe_Dude
fonte