2010-02-19 8 views
70

¿Es posible eliminar el hash de window.location sin hacer que la página salte-vaya a la parte superior? Necesito poder modificar el hash sin causar ningún salto.¿Cómo puedo eliminar el hash de ubicación sin hacer que la página se desplace?

tengo esto:

$('<a href="#123">').text('link').click(function(e) { 
    e.preventDefault(); 
    window.location.hash = this.hash; 
}).appendTo('body'); 

$('<a href="#">').text('unlink').click(function(e) { 
    e.preventDefault(); 
    window.location.hash = ''; 
}).appendTo('body'); 

véase el ejemplo vivo aquí: http://jsbin.com/asobi

Cuando el usuario hace clic 'enlace' la etiqueta de hash se modifica sin saltos de página, por lo que está funcionando bien.

Pero cuando el usuario hace clic en 'unlink' se ha eliminado la etiqueta de has y la página se desplaza hacia la parte superior. Necesito eliminar el hash sin este efecto secundario.

+0

Déjame adivinar: el cliente piensa que el hash es feo y está contaminando la URL de otra manera agradable y limpio, que dice lo siguiente: http: // www.example.com/ (sin los espacios en blanco)? – anddoutoi

+0

Buena conjetura, pero no. Tengo ventanas modales bookmarkable basadas en direcciones hash, y cuando el usuario cierra la ventana, el hash debe ir. – David

+1

Soy consciente de que esta pregunta tiene casi 2 años, pero este comentario puede ayudar a un lector futuro. Si realmente desea eliminar el hash, puede cambiar la url usando history.pushState(). https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history#Example – ambiguousmouse

Respuesta

90

Creo que si solo pones un hash ficticio, no se desplazará ya que no hay coincidencia para desplazarte.

<a href="#A4J2S9F7">No jumping</a> 

o

<a href="#_">No jumping</a> 

"#" por sí mismo es equivelent a "_top" por lo tanto provoca un desplazamiento hacia la parte superior de la página

+11

No es óptimo, pero es lo suficientemente bueno. Usé '# /' con el mismo resultado. – David

+2

whoooooooooooop gracias .. amigo. – CraftyFella

+0

'window.location.hash = (new_hash === '')? '_': new_hash; ' – tester

1

No estoy seguro si esto produce el resultado deseado, darle un disparo:

$('<a href="#">').text('unlink').click(function(e) { 
    e.preventDefault(); 
    var st = parseInt($(window).scrollTop()) 
    window.location.hash = ''; 
    $('html,body').css({ scrollTop: st }); 
}); 

Básicamente, guarde el desplazamiento de desplazamiento y vuelva a guárdelo después de asignar el hash vacío.

+1

me funciona, excepto que utilizo '$ (window) .scrollTop (st)' en vez de '.css()' –

+0

Probé este, ya que necesito _need_ para cambiar el hash a un #id existente. Todo funciona bien, pero cuando trato de desplazarme con el mouse, después de cambiar el hash, el scroll salta a cero. Alguna idea sobre lo que podría causar esto? – lucascaro

18

La propiedad hash de window.location es estúpida en un par de formas. Este es uno de ellos; la otra es que tiene diferentes get y valores establecidos:

window.location.hash = "hello"; // url now reads *.com#hello 
alert(window.location.hash); // shows "#hello", which is NOT what I set. 
window.location.hash = window.location.hash; // url now reads *.com##hello 

Tenga en cuenta que al establecer la propiedad de hash a '' quita la marca de hash también; eso es lo que redirige a la página. Para establecer el valor de la parte hash de la url para '', dejando la marca hash y por lo tanto no refrescante, escribir lo siguiente:

window.location.href = window.location.href.replace(/#.*$/, '#'); 

No hay manera de eliminar por completo la almohadilla una vez establecido sin actualizar la página .

ACTUALIZACIÓN 2012:

Como Blazemonger y thinkdj han señalado, la tecnología ha mejorado. Algunos navegadores te permiten borrar ese hashtag, pero otros no. Para apoyar tanto, intentar algo como:

if (window.history && window.history.pushState) { 
    window.history.pushState('', '', window.location.pathname) 
} else { 
    window.location.href = window.location.href.replace(/#.*$/, '#'); 
} 
+2

No es cierto. Los navegadores compatibles con 'window.history' le permiten hacer exactamente esto. – Blazemonger

+0

@Blazemonger ¡Es cierto! Puede usar history.pushState ('', document.title, window.location.pathname); –

+0

Pero, de nuevo, este comentario se realizó en Feb'10 y los navegadores comenzaron a respaldar pushstates alrededor de mediados de 2011 –

1

¿Ha intentado return false; en el controlador de eventos? jQuery hace algo especial cuando haces eso, similar a, pero AFAIK más impactante, que e.preventDefault.

+2

'return false;' en jQuery y en controladores de eventos nativos en navegadores compatibles es equivalente a 'e.preventDefault(); mi.stopPropagation(); '. No creo que detener la propagación ayude con este problema. –

1

Al establecer window.location.hash en empty o en el nombre de anclaje no existente, siempre forzará a la página a saltar a la parte superior. La única manera de evitar esto es tomar la posición de desplazamiento de la ventana y establecerla en esa posición nuevamente después del cambio de hash.

Esto también obligará a volver a pintar la página (no puedo evitarlo), aunque como se ejecuta en un solo proceso js, ​​no saltará arriba/abajo (teóricamente).

$('<a href="#123">').text('link').click(function(e) { 
    e.preventDefault(); 
    window.location.hash = this.hash; 
}).appendTo('body'); 

$('<a href="#">').text('unlink').click(function(e) { 
    e.preventDefault(); 
    var pos = $(window).scrollTop(); // get scroll position 
    window.location.hash = ''; 
    $(window).scrollTop(pos); // set scroll position back 
}).appendTo('body'); 

Espero que esto ayude.

+1

no es del todo correcto ... al configurar el hash para "" se desplaza hacia la parte superior, pero si no hay un anclaje con nombre o elemento con un atributo 'id' coincidente, el navegador no se desplazará. – scunliffe

32

Utilizo lo siguiente en algunos sitios, ¡NO HAY SALIDAS DE PÁGINA!

Bonita barra de direcciones limpia para navegadores amigables HTML5, y solo un # para navegadores más antiguos.

$('#logo a').click(function(e){ 
    window.location.hash = ''; // for older browsers, leaves a # behind 
    history.pushState('', document.title, window.location.pathname); // nice and clean 
    e.preventDefault(); // no page reload 
}); 
+10

'history.replaceState' podría ser preferible, ya que presionar hacia atrás regresará a la última URL * válida *. – orlade

+0

Además, debe tenerse en cuenta que este código se establece haciendo dos cambios en el historial de navegación. El resultado es que cuando el usuario presiona el botón Atrás, se enrutará primero a través de [url] # y luego se requerirá un segundo clic para aterrizar en [url] sin el #. Si está desarrollando la experiencia del botón Atrás, considere un enfoque condicional para no establecer el estado dos veces. –

3

Ésta es una entrada antigua, pero yo quería compartir mi solución Todos los enlaces en mi proyecto que se manejan de JS están teniendo href = "#_ js" atributo (o el nombre que desea utilizar para ese sólo con fines), y en la página de inicialización que hacen:

$('body').on('click.a[href="#_js"]', function() { 
    return false; 
}); 

eso basta el truco

0

esperanza esto ayuda

html

<div class="tabs"> 
    <ul> 
    <li><a href="#content1">Tab 1</a></li> 
    <li><a href="#content2">Tab 2</a></li> 
    <li><a href="#content3">Tab 3</a></li> 
    </ul> 
</div> 
<div class="content content1"> 
    <p>1. Content goes here</p> 
</div> 
<div class="content content2"> 
    <p>2. Content goes here</p> 
</div> 
<div class="content content3"> 
    <p>3. Content goes here</p> 
</div> 

js

function tabs(){ 
    $(".content").hide(); 

    if (location.hash !== "") { 
    $('.tabs ul li:has(a[href="' + location.hash + '"])').addClass("active"); 
    var hash = window.location.hash.substr(1); 
    var contentClass = "." + hash; 
    $(contentClass).fadeIn(); 
    } else { 
    $(".tabs ul li").first().addClass("active"); 
    $('.tabs').next().css("display", "block"); 
    } 
} 
tabs(); 

$(".tabs ul li").click(function(e) { 
    $(".tabs ul li").removeAttr("class"); 
    $(this).addClass("active"); 
    $(".content").hide(); 
    var contentClass = "." + $(this).find("a").attr("href").substr(1); 
    $(contentClass).fadeIn(); 
    window.location.hash = $(this).find("a").attr("href"); 
    e.preventDefault(); 
    return false; 
}); 

URL sin ningún tipo de patata.
http://output.jsbin.com/tojeja

URL con un hashtag que no se lanza al ancla.
http://output.jsbin.com/tojeja#content1

Cuestiones relacionadas