Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery this.hash behavior for in page anchor links

I have a question about how this.hash works for in page anchor links in jQuery.

I need to process the hash attribute every time the user clicks on that link.

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

For the above HTML snippet, when I fetch the hash attribute, everything works fine.

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

However, when I use name attribute instead of id attribute for the target, this.hash returns a null object.

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

In this case, the click event does not fire the alert.

The full example is here

Can someone explain what I am missing over here or if this is how it is supposed to work?

like image 652
Gunner4Life Avatar asked Mar 11 '12 17:03

Gunner4Life


2 Answers

this.hash will return "#foo" which is also a valid ID selector [docs]. Hence $(this.hash) is the same as $("#foo") and will select the element with ID foo.
In your second example, you don't have an element with ID bar. Thus $(this.hash) won't select any element and target.length will be 0.


Maybe you are confused by the fact that the browser still jumps to <a name="bar"></a>, although the alert is not shown. The browser does not behave the same as jQuery.

From the HTML specification about the name attribute:

This attribute names the current anchor so that it may be the destination of another link. The value of this attribute must be a unique anchor name. The scope of this name is the current document. Note that this attribute shares the same name space as the id attribute.

So if the browser recognises a hash (fragment identifier) in the URL, it tries to find the first element with this ID or the first a element with that name.

In contrast, CSS ID selectors (that's what jQuery is using) only search for elements with that ID, not for (a) elements with that name. Internally, jQuery is using document.getElemenById.


If the hash value is always referring to either an ID or a name, you can use the multiple selector to just make one selection:

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

In case there would be an element with this ID and an anchor with this name, you'd select all of them though.

like image 58
Felix Kling Avatar answered Nov 06 '22 00:11

Felix Kling


because the selector $(this.hash) finds nothing in the second case, this.hash return #foo and then $("#foo") looks for the element with id foo which in the second case return nothing

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

like image 1
Rafay Avatar answered Nov 06 '22 00:11

Rafay