使用完全限定的URL在Sizzle中选择元素的方法

在最近编写脚本时,我遇到了Sizzle如何使用href属性的特殊细微差别。 具体来说,在href上使用属性选择器,Sizzle将使用实际属性值:

 // Will not find ... $('a[href="http://www.example.com/https://stackoverflow.com/questions/9222026/method-for-selecting-elements-in-sizzle-using-fully-qualified-urls/index.html"]') 

Sizzle使用.getAttribute()而不是elem.href (或更确切地说, elem['href'] ,正如Sizzle在大多数情况下所做的那样 ); elem.href将提供完全限定的URL。

为了更多地理解这一点,我创建了一个小提琴来尝试不同forms的URL 。 在测试过程中,我发现设置href等于自身的(显而易见的)“解决方案”:

 $('a').each(function(){ this.href = this.href; }); 

毫不奇怪,更新元素以反映this.href提供的完全限定的URL。 还有其他方法我发现工作(任何更新元素的href属性),但他们只是将上述方法移植到其他forms,或涉及像.filter() (演示)的东西 :

 var matches = $('a').filter(function(){ var window_location = 'http://example.com/services.html'; return window_location == this.href; }); 

我之所以这么说是因为在选择之前做el.href = el.href是某种意义上的解决方法(我不认为这是一个很好的选择)。 例如,如果可以,则运行对一组元素的检查以查找是否包含与当前URL(或其他URL)的匹配链接,这样做更容易:

 $links.not('[href="' + window.location.href + '"]') 

有没有办法做到这一点,而不必诉诸“更新”属性,或编写额外的代码来管理支票? 有没有一种方法我忽略了不涉及修改Sizzle的工作方式^

^注意 :与仅添加expression相比,修改实际源代码将是一个(坏)想法:

 $.extend($.expr[':'], { url: function(elem, i, match){ return elem.href === match[3]; } }); var $matched = $('a:url(http://test.com/https://stackoverflow.com/questions/9222026/method-for-selecting-elements-in-sizzle-using-fully-qualified-urls/index.html)'); 

http://jsfiddle.net/yt2RU/

(另外,在Sizzle中是否存在其他具有类似非典型行为的属性?)

我相信我已经得到了这个问题的答案……

使用expression

 jQuery.extend(jQuery.expr[':'], { url: function(elem, i, match){ return elem.href === match[3]; } }); var $matched = jQuery('a:url(http://test.com/index.html)'); 

http://jsfiddle.net/yt2RU/

或者,正如评论中指出的那样,可以使用$.filter()

 var $matched = $('a').filter(function(){ if (this.href == 'http://test.com/index.html') { return true; } return false; }); 

http://jsfiddle.net/dMuyj/

如果querySelector()querySelectorAll()本身不可用,那jQuery只会回到Sizzle,并且这两个都与jQuery的选择器引擎相同(不奇怪)。

总和是,如果您需要这种类型的选择器,您需要一个表达式或filter,并使用elem.href进行比较,而不是getAttribute()