2012-03-11 14 views
13

Ho una domanda su come funziona this.hash nei collegamenti di ancoraggio della pagina in jQuery.jQuery comportamento.shsh per i collegamenti di ancoraggio in pagina

Ho bisogno di elaborare l'attributo hash ogni volta che l'utente fa clic su quel collegamento.

<a href="#foo" class="inpageLink">Click Me!<"/a> 
... 
... 
<a id="foo"></a> 
<h3>Target Location</h3> 

Per il frammento HTML sopra riportato, quando recupero l'attributo hash, tutto funziona correttamente.

Tuttavia, quando uso l'attributo nome anziché l'attributo id per la destinazione, this.hash restituisce un oggetto nullo.

<a href="#bar" class="inpageLink">Click Me!</a> 
<a name="bar"></a> 
<h3>Target Location</h3> 

In questo caso, l'evento click non attiva l'avviso.

The full example is here

qualcuno può spiegare che cosa manco qui o se questo è come dovrebbe funzionare?

+0

attributo Il nome non è lo stesso che l'attributo id. Il nome viene in genere utilizzato per indicare il nome da utilizzare per un parametro del modulo. Oltre a questo, è praticamente inutile. – jjm

+0

@jjm: viene utilizzato anche per le ancore. Dato URL 'http: // example.com/# foo', il browser salterà all'elemento con ID' pippo' o all'elemento 'a' con nome' pippo'. Vedi http://www.w3.org/TR/html4/struct/links.html#h-12.2 –

risposta

26

this.hash restituirà "#foo" che è anche un valido ID selector[docs]. Quindi lo $(this.hash) è lo stesso di $("#foo") e selezionerà l'elemento con IDfoo.
Nel secondo esempio, non si dispone di un elemento con ID bar. Pertanto, $(this.hash) non selezionerà alcun elemento e target.length sarà 0.


Forse si sono confusi dal fatto che il browser salti ancora <a name="bar"></a>, anche se il alert non viene mostrato. Il browser non si comporta come jQuery.

Dal HTML specification about the name attribute:

nomi Questo attributo l'ancora corrente in modo che possa essere la destinazione di un altro collegamento. Il valore di questo attributo deve essere un nome di ancoraggio univoco. Lo scopo di questo nome è il documento corrente. Si noti che questo attributo condivide lo stesso spazio dei nomi dell'attributo id.

Quindi, se il browser riconosce un hash (identificatore di frammento) nell'URL, si cerca di trovare il primo elemento con questo ID o il primo a elemento con quel nome.

Al contrario, i selettori ID CSS (quello che jQuery sta utilizzando) cercano solo elementi con quell'ID, non per (a) elementi con quel nome. Internamente, jQuery utilizza document.getElemenById.


Se il valore di hash è sempre riferendosi a uno un ID o un nome, è possibile utilizzare il multipla di selezione per fare un solo selezione:

$(this.hash + ', a[name="' + this.hash.substr(1) + '"]') 

Nel caso in cui ci sarebbe stato un elemento con questo ID e un'ancora con questo nome, tuttavia selezioneresti tutti.

+2

+1 Risposta perfetta –

+0

Felix, grazie per la spiegazione. Penso di capire cosa sta succedendo ora. Non ho il controllo sulla determinazione se otterrò un ID o un nome sul bersaglio. Ho finito per risolvere questo problema vedendo prima se $ (this.hash) esiste. In caso contrario, esegui una query per $ ('[nome =' + this.hash.substring (1) + ']'). Se questo non esiste, faccio semplicemente retrocedere e lasciare che il browser faccia l'evento di clic predefinito! Mi aspettavo che jQuery facesse questo per me, ma vabbè! – Gunner4Life

+0

@ Gunner4Life: se è sempre un ID o un nome, puoi usare un solo selettore: '$ (this.href + ', a [name ="' + this.href.substr (1) + '"]') '. Ho usato 'href' perché penso che sia più conforme (potrebbe essere sbagliato però;)). –

1

perché il selettore $(this.hash) trova niente, nel secondo caso, this.hash ritorno #foo e poi $("#foo") guarda per l'elemento con id foo, che nel secondo caso di ritorno nulla

http://jsfiddle.net/BQU3u/5/

0

perché non possiamo usare attr ('href') - controllare questo link

http://jsfiddle.net/BQU3u/11/

Aggiornamento

sufficiente rimuovere $ da $ (this.hash)

http://jsfiddle.net/BQU3u/12/

+0

Non possiamo, ma come risponde questa domanda? Il tuo violino è imperfetto 'target' contiene una stringa ora che non è vuota, quindi la sua lunghezza è sempre diversa da' 0'. Nel codice originale, 'target' si riferiva ad un oggetto jQuery. –

+0

Ma in questo funziona. –

+0

No. Solo ** sembra ** funzionare, perché hai cambiato a cosa si riferisce il target. Il codice equivalente sarebbe 'target = $ ($ (this) .attr ('href'));' (notare l'addizionale '$ (...)'). Il tuo violino non è quello che l'OP vuole fare e la tua argomentazione si basa su una premessa sbagliata. Se vuoi mostrare qualcosa, devi replicare il comportamento del codice dell'OP, non cambiarlo. –

Problemi correlati