2012-03-11 9 views
13

Tengo una pregunta acerca de cómo funciona this.hash en enlaces de anclaje de página en jQuery.jQuery this.hash Comportamiento en enlaces de anclaje de página

Necesito procesar el atributo de hash cada vez que el usuario hace clic en ese enlace.

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

Para el fragmento HTML anterior, cuando obtengo el atributo hash, todo funciona bien.

$('.inpageLink').click(function(){ 
    var target = $(this.hash); 
    if (target.length != 0) { 
     alert("found target" + this.hash); 
    } 
}) 

Sin embargo, cuando uso atributo de nombre en lugar de atributo de identificación para el objetivo, this.hash devuelve un objeto nulo.

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

En este caso, el evento click no activa la alerta.

The full example is here

¿Puede alguien explicar lo que me falta aquí o si esta es la forma en que se supone que funciona?

+0

El nombre del atributo no es el mismo que el atributo id. El nombre se usa generalmente para indicar el nombre que se debe usar para un parámetro de formulario. Aparte de eso, es bastante inútil. – jjm

+0

@jjm: también se usa para anclajes. Dado el URL 'http: // example.com/# foo', el navegador saltará al elemento con ID' foo' o al elemento 'a' con el nombre' foo'. Ver http://www.w3.org/TR/html4/struct/links.html#h-12.2 –

Respuesta

26

this.hash devolverá "#foo" que también es un ID selector[docs] válido. Por lo tanto, $(this.hash) es lo mismo que $("#foo") y seleccionará el elemento con IDfoo. En el segundo ejemplo, no tiene un elemento con ID bar. Por lo tanto, $(this.hash) no seleccionará ningún elemento y target.length será 0.


Quizás esté confundido por el hecho de que el navegador todavía salta a <a name="bar"></a>, aunque el alert no se muestra. El navegador no se comporta igual que jQuery.

Desde el HTML specification about the name attribute:

nombres de este atributo el ancla actual, de modo que puede ser el destino de otro enlace. El valor de este atributo debe ser un nombre de ancla único. El alcance de este nombre es el documento actual. Tenga en cuenta que este atributo comparte el mismo espacio de nombre como el atributo id.

Así que si el navegador reconoce un hash (identificador de fragmento) en la URL, se trata de encontrar el primer elemento con este ID o el primer elemento de a con ese nombre.

Por el contrario, los selectores de ID de CSS (eso es lo que usa jQuery) solo buscan elementos con esa ID, no para elementos (a) con ese nombre. Internamente, jQuery usa document.getElemenById.


Si el valor hash siempre se refiere a cualquiera de una identificación o un nombre, puede utilizar la selector múltiple de hacer sólo una selección:

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

En caso habría un elemento con este ID y un ancla con este nombre, sin embargo, los seleccionaría a todos.

+2

+1 Respuesta perfecta –

+0

Félix, gracias por la explicación. Creo que entiendo lo que está pasando ahora. No tengo control para determinar si obtendré una identificación o un nombre en el objetivo. Terminé resolviendo esto al ver primero si $ (this.hash) existe. Si no es así, haciendo una consulta para $ ('[name =' + this.hash.substring (1) + ']'). Si eso no existe, simplemente retrocedo y dejo que el navegador haga el evento de clic predeterminado. Esperaba que jQuery hiciera esto por mí, ¡pero bueno! – Gunner4Life

+0

@ Gunner4Life: si siempre es una identificación o un nombre, puede usar un selector: '$ (this.href + ', a [name ="' + this.href.substr (1) + '"]') '. Utilicé 'href' porque creo que es más estándar (aunque podría estar equivocado;)). –

1

porque el selector de $(this.hash) no encuentra nada en el segundo caso, this.hash retorno #foo y luego $("#foo") busca el elemento con id foo, que en el segundo caso el retorno nada

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

0

por qué no podemos usar attr ('href') - verificar este enlace

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

actualización

basta con quitar de $ $ (this.hash)

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

+0

Podemos pero, ¿cómo responde esto a la pregunta? Tu violín está defectuoso por cierto. 'target' contiene una cadena ahora que no está vacía, por lo que su longitud siempre es diferente de' 0'. En el código original, 'target' se refería a un objeto jQuery. –

+0

Pero en esto funciona. –

+0

No. Solo ** parece ** funcionar, porque ha cambiado a lo que se refiere 'target'. El código equivalente sería 'target = $ ($ (this) .attr ('href'));' (tenga en cuenta el adicional '$ (...)'). Tu violín no hace lo que OP quiere hacer y tu argumentación se basa en una premisa falsa. Si desea mostrar algo, debe replicar el comportamiento del código del OP, no cambiarlo. –

Cuestiones relacionadas