While working on a script recently, I came across a peculiar nuance of how Sizzle works with the href
attribute. Specifically, using an attribute selector on an href
, Sizzle will use the actual attribute value:
// Will not find <a href="index.html">...
$('a[href="http://www.example.com/index.html"]')
Sizzle uses .getAttribute()
instead of elem.href
(or more precisely, elem['href']
, as Sizzle does in most cases); elem.href
would provide the fully-qualified URL.
To understand this a bit more, I created a fiddle to try different forms of URLs. In the process of testing, I discovered the (obvious) "solution" of setting the href
equal to itself:
$('a').each(function(){
this.href = this.href;
});
Which, unsurprisingly, updates the element to reflect the fully-qualified URL that this.href
provides. There are other ways I've found that work (any that update the href
attribute of an element), but they just port the above approach to other forms, or involve something like .filter()
(demo):
var matches = $('a').filter(function(){
var window_location = 'http://example.com/services.html';
return window_location == this.href;
});
The reason I say this is that doing el.href = el.href
before selecting is a workaround in a sense (and one I don't think is a great alternative). For instance, running a check on a set of elements to find if any contain a matching link to the current URL (or another URL) is simpler to do if you can:
$links.not('[href="' + window.location.href + '"]')
Is there a way to do this without having to resort to "updating" the attributes, or writing additional code to manage the check? Is there a way I've overlooked that doesn't involve modifying how Sizzle works ^?
^ Note: Modifying the actual source code would be a (bad) idea compared to just adding an expression
:
$.extend($.expr[':'], {
url: function(elem, i, match){
return elem.href === match[3];
}
});
var $matched = $('a:url(http://test.com/index.html)');
http://jsfiddle.net/yt2RU/
(And as an aside, are there other attributes with similar untypical behavior in Sizzle?)
See Question&Answers more detail:
os