最近在编写脚本时,我发现了 Sizzle 如何与属性一起使用的href
特殊细微差别。具体来说,在 上使用属性选择器href
,Sizzle 将使用实际的属性值:
// Will not find <a href="index.html">...
$('a[href="http://www.example.com/index.html"]')
Sizzle 使用.getAttribute()
代替elem.href
(或更准确地说elem['href']
,就像Sizzle 在大多数情况下所做的那样);elem.href
将提供完全限定的 URL。
为了进一步理解这一点,我创建了一个小提琴来尝试不同形式的 URL。在测试过程中,我发现了将 equal 设置href
为自身的(明显的)“解决方案” :
$('a').each(function(){
this.href = this.href;
});
毫不奇怪,它会更新元素以反映所this.href
提供的完全限定 URL。我发现还有其他方法可以工作(任何更新href
元素属性的方法),但它们只是将上述方法移植到其他形式,或涉及类似.filter()
(demo)的内容:
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/index.html)');
(顺便说一句,在 Sizzle 中是否还有其他具有类似非典型行为的属性?)