最近在编写脚本时,我遇到了 how Sizzle works 的一个特殊细微差别。与 the href
attribute .具体来说,在 href
上使用属性选择器,Sizzle 将使用实际的属性值:
// Will not find <a href="index.html">...
$('a[href="http://www.example.com/index.html"]')
Sizzle 使用 .getAttribute()
而不是 elem.href
(或更准确地说,elem['href']
,如 Sizzle does in most cases ); elem.href
将提供完全限定的 URL。
为了更深入地理解这一点,我创建了一个指向 try different forms of URLs 的 fiddle .在测试过程中,我发现了 setting the href
equal to itself 的(明显的)“解决方案” :
$('a').each(function(){
this.href = this.href;
});
毫不奇怪,它会更新元素以反射(reflect) 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 的工作方式 ^?
^ 注意:与仅添加表达式
相比,修改实际源代码将是一个(坏)主意:
$.extend($.expr[':'], {
url: function(elem, i, match){
return elem.href === match[3];
}
});
var $matched = $('a:url(http://test.com/index.html)');
(顺便说一句,在 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)');
或者,如评论中所述,可以使用 $.filter()
:
var $matched = $('a').filter(function(){
if (this.href == 'http://test.com/index.html') {
return true;
}
return false;
});
并且 jQuery 仅在 querySelector()
时回退到 Sizzle和 querySelectorAll()
本地不可用,并且这两者的工作方式与 jQuery 的选择器引擎相同(不足为奇)。
总而言之,如果您需要这种类型的选择器,则需要表达式或过滤器,并使用 elem.href
进行比较,而不是 getAttribute()
.
关于javascript - 使用完全限定的 URL 在 Sizzle 中选择元素的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9222026/