salto de ancla usando javascript

129

Tengo una pregunta que se encontrará con mucha frecuencia. El problema es que en ninguna parte se puede encontrar una solución explícita.

Tengo dos problemas con respecto a las anclas.

El objetivo principal debe ser obtener una URL limpia y agradable sin ningún hash en ella mientras se utilizan anclas para saltar en una página.

Entonces la estructura de los anclajes es:

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

De acuerdo, si hace clic en uno de los enlaces, la URL cambiará automáticamente a

www.dominio.com/página#1

Al final esto debería ser solo:

www.dominio.com/página

Hasta aquí todo bien. Ahora, la segunda cosa es que cuando busques en Internet ese problema, encontrarás javascriptuna solución.

He encontrado esta función:

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

y llamando a esa función con:

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

como será igual antes Agregará el hash a la url. También agregué

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

sin éxito. Entonces, si hay alguien que pueda decirme cómo resolver esto, realmente lo agradecería.

Muchas gracias.

hermoso
fuente
No estoy seguro de esto, pero podría intentar escribir manualmente en la propiedad hash después del salto. Por ejemplo, establezca un tiempo de espera en el controlador onclick que establece window.location.hash=''.
Jeff
¿Quiere decir que no desea que se muestre el # en la URL al saltar a otra sección en la misma página web?
Roger Ng
2
En ese caso, tendrá que manipular el scrollTop de la ventana, generalmente por window.scrollToo el jQuery helper correspondiente: stackoverflow.com/questions/6677035/jquery-scroll-to-element o stackoverflow.com/questions/500336/…
Frank van Puffelen
@Jeff: si lo haces location.hash='', los #restos permanecen allí.
Derek 朕 會 功夫
No hagas eso, por favor. Los hash son buenos al guardar la página en sus marcadores.
Marco Sulla

Respuestas:

204

Puede obtener la coordenada del elemento de destino y establecer la posición de desplazamiento. Pero esto es muy complicado.

Aquí hay una manera más perezosa de hacer eso:

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

Esto se utiliza replaceStatepara manipular la url. Si también desea soporte para IE , deberá hacerlo de la manera 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
}​

Demostración: http://jsfiddle.net/DerekL/rEpPA/
Otro con transición: http://jsfiddle.net/DerekL/x3edvp4t/

También puedes usar .scrollIntoView:

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

(Bueno, mentí. No es complicado en absoluto).

Derek 朕 會 功夫
fuente
1
¡Ratas! El enlace está roto :-( Pensé que JS Fiddles se quedó allí para siempre
Mawg dice que reinstale a Monica el
1
@Mawg Aparentemente, han eliminado la capacidad de usar agregar /showal final de la url.
Derek 朕 會 功夫
11
"Incluso IE6 admite esto" es el mejor comentario que he visto.
Josh
3
@Black No existe el elemento "jQuery". Si desea obtener el primer elemento de su consulta, hágalo $(mySelector)[0].scrollIntoView().
Derek 朕 會 功夫
44
1+ para scrollIntoView. 1- por mencionarlo al final.
Yay295
12

Creo que es una solución mucho más simple:

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

Este método no recarga el sitio web y establece el foco en los anclajes necesarios para el lector de pantalla.

Adam111p
fuente
Y lo que rara vez funciona en IE, esto funciona en todos los IE;)
Adam111p
55
Terminé conwindow.location = window.location.origin + window.location.pathname + '#hash';
Alex
Esto volvió a cargar la página para mí. Sin embargo, la respuesta aceptada terminó funcionando, ojalá fuera más corta.
HoldOffHunger
3

No hay suficiente representante para un comentario.

El método basado en getElementById () en la respuesta seleccionada no funcionará si el ancla se ha establecido namepero no se ha idestablecido (lo cual no se recomienda, pero sucede en la naturaleza).

Algo a tener en cuenta si no tiene el control del marcado del documento (por ejemplo, webextension).

El locationmétodo basado en la respuesta seleccionada también se puede simplificar con location.replace:

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

Porque cuando lo haces

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

Cargas una nueva página, puedes hacer:

<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
fuente
3
No creo que agregar hashes la convierta en una nueva página.
Derek 朕 會 功夫
55
No vuelve a cargar la página.
Derek 朕 會 功夫
Tienes razón, no vuelve a cargar la página. Intento en la consola con Chrome y el favicon se vuelve a cargar.
Jonathan Vukovich-Tribouharet
En el último Firefox, los cambios hash parecen forzar una recarga para iFrames (en el atributo src). Consideraría esto un error del navegador, pero algo a tener en cuenta.
Beejor
1

Tengo un botón para un mensaje que al hacer clic se abre el diálogo de visualización y luego puedo escribir lo que quiero buscar y se dirige a esa ubicación en la página. Utiliza javascript para responder al encabezado.

En el archivo .html tengo:

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

En el archivo .js tengo

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

Cuando escribo test100 en el indicador, irá a donde he colocado span id = "test100" en el archivo html.

Yo uso Google Chrome.

Nota: Esta idea proviene de vincular en la misma página usando

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

que al hacer clic se enviará al ancla. Para que funcione varias veces, por experiencia debe volver a cargar la página.

El crédito a la gente en stackoverflow (y posiblemente stackexchange, también) no puede recordar cómo reuní todos los fragmentos. ☺

S.Doe_Dude
fuente