2010-02-19 9 views
70

E 'possibile rimuovere l'hash da window.location senza far scorrere la pagina verso l'alto? Devo essere in grado di modificare l'hash senza causare salti.Come posso rimuovere l'hash della posizione senza far scorrere la pagina?

ho questo:

$('<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'); 

vedi esempio vivo qui: http://jsbin.com/asobi

Quando 'collegamento' l'utente seleziona il tag hash viene modificato senza qualsiasi pagina, salti, in modo che sta lavorando bene.

Ma quando l'utente fa clic su "scollega" il tag has viene rimosso e lo scroll della pagina salta in alto. Devo rimuovere l'hash senza questo effetto collaterale.

+0

Lasciami indovinare: il tuo cliente pensa che l'hash è brutto e sta inquinando l'URL bello e altrimenti pulito che legge: http: // www.example.com/ (senza lo spazio bianco)? – anddoutoi

+0

Buona ipotesi, ma no. Ho finestre modali con segnalibro basate su hash URL e quando l'utente chiude la finestra, l'hash deve andare. – David

+1

Sono consapevole che questa domanda ha quasi 2 anni, ma questo commento può aiutare un futuro lettore. Se si desidera rimuovere l'hash, è possibile modificare l'URL utilizzando history.pushState(). https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history#Example – ambiguousmouse

risposta

90

Credo che se si inserisce un hash fittizio non scorrerà perché non vi è alcuna corrispondenza con cui scorrere.

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

o

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

"#" di per sé è equivelent a "_top" provoca quindi un rotolo alla parte superiore della pagina

+11

Non ottimale, ma abbastanza buono. Ho usato "# /" con lo stesso risultato. – David

+2

whoooooooooooop grazie .. amico. – CraftyFella

+0

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

1

Non sono sicuro se questo produce il risultato desiderato, dare uno scatto:

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

In pratica salvare lo scorrimento di scorrimento e ri memorizzarlo dopo aver assegnato l'hash vuoto.

+1

funziona per me, eccetto che uso '$ (window) .scrollTop (st)' invece di '.css()' –

+0

Provato questo, dato che ho bisogno di _ cambiare l'hash a un #id esistente. Tutto funziona bene, ma quando provo a scorrere usando il mouse, dopo aver cambiato l'hash, lo scroll salta a zero. Qualche idea su cosa potrebbe causare questo? – lucascaro

18

La proprietà hash di window.location è stupida in un paio di modi. Questo è uno di loro; L'altra è che è ha ottenere diversi e valori impostati:

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 

Si noti che l'impostazione della proprietà di hash per '' rimuove il cancelletto troppo; questo è ciò che reindirizza la pagina. Per impostare il valore della parte hash della url '', lasciando il cancelletto e quindi non rinfrescante, scrivere questo:

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

Non v'è alcun modo per rimuovere completamente il carattere cancelletto una volta impostato senza aggiornare la pagina .

UPDATE 2012:

Come Blazemonger e thinkdj hanno sottolineato, la tecnologia è migliorata. Alcuni browser ti consentono di cancellare l'hashtag, ma altri no. Per supportare entrambi, provare qualcosa di simile:

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

Non vero. I browser che supportano 'window.history' ti permettono di fare esattamente questo. – Blazemonger

+0

@Blazemonger È vero! Puoi usare history.pushState ('', document.title, window.location.pathname); –

+0

Ma, ancora una volta, questo commento è stato fatto nel febbraio 10 e i browser hanno iniziato a supportare i pushstates da qualche parte verso la metà del 2011 –

1

Hai provato return false; nel gestore di eventi? jQuery fa qualcosa di speciale quando lo fai, simile a, ma AFAIK più di impatto, rispetto a e.preventDefault.

+2

'return false;' in jQuery e nei gestori di eventi nativi nei browser compatibili equivale a 'e.preventDefault(); e.stopPropagation(); '. Non credo che l'interruzione della propagazione possa aiutare con questo problema. –

1

L'impostazione di window.location.hash per il nome dell'ancoraggio vuoto o non esistente, imporrà sempre la pagina a saltare in alto. L'unico modo per evitare ciò è afferrare la posizione di scorrimento della finestra e impostarla nuovamente su quella posizione dopo la modifica dell'hash.

Questo forzerà anche un ridisegno della pagina (non posso evitarlo), anche se poiché è eseguito in un singolo processo js, ​​non salterà su/giù (in teoria).

$('<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'); 

Spero che questo aiuti.

+1

non completamente corretto ... impostando l'hash su "" scorre verso l'alto, ma se non c'è un ancoraggio o elemento con un attributo 'id' corrispondente, il browser non scorrerà. – scunliffe

32

Io uso il seguente su alcuni siti, NESSUN INCONTRO PAGINA!

Bella barra degli indirizzi pulita per i browser HTML5 e solo una # per i browser più vecchi.

$('#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' potrebbe essere preferibile, poiché premendo indietro si tornerà all'ultimo URL * valido *. – orlade

+0

Inoltre, è necessario notare che questo codice è impostato per apportare due modifiche alla cronologia di navigazione. Il risultato è che quando l'utente preme il pulsante Indietro, verrà prima instradato attraverso [url] # e quindi richiederà un secondo clic per atterrare su [url] senza il #. Se stai sviluppando l'esperienza del pulsante Indietro, considera un approccio condizionale in modo da non impostare lo stato due volte. –

3

Questo è un vecchio post, ma ho voluto condividere la mia soluzione Tutti i link nel mio progetto che in corso di trattazione da JS stanno avendo href = "#_ js" attributo (o qualsiasi altro nome che si desidera utilizzare per questo scopi soltanto), e sulla pagina di inizializzazione che faccio:

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

Basta così il trucco

0

Spero che questo aiuti

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 senza alcuna hash.
http://output.jsbin.com/tojeja

URL con hashtag che non salta all'ancora. http://output.jsbin.com/tojeja#content1

Problemi correlati