【问题标题】:JQuery: Finding/Filtering on attributes within contextJQuery:在上下文中查找/过滤属性
【发布时间】:2010-10-11 22:15:51
【问题描述】:

我一直在尝试几种不同的方法来过滤在我的 html 中找到的特定节点。

这里是一些示例 html:

<body>
    <div ui:component="component1"></div>
    <ul ui:component="component2"></ul>
    <article ui:component="component3"></article>
</body>

我已经通过一个简单的过滤器成功地匹配了项目:

// returns div, ul, article
$('[ui\\:component]').each();

但是,当我开始根据父节点过滤它时,它开始对我失败。我试过了:

$('[ui\\:component]', $('body'));   // returns []
$('body').find('[ui\\:component]'); // returns []
$('body').filter('[ui\\:component]'); // returns []
$('body').find('*').filter('[ui\\:component]'); // returns []

我在这里做错了什么?起初我以为它可能是 ui 命名空间,但将其添加到 html doc 或 body 似乎没有任何意义。非常感谢帮助

全文如下:

<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
</head>
<body>
    <div ui:component="component1"></div>
    <ul ui:component="component2"></ul>
    <article ui:component="component3"></article>
</body>
<script type="text/javascript">
$(document).ready(function() {

    // returns div, ul, article
    console.log($('[ui\\:component]'));

    // these all return nada
    console.log($('[ui\\:component]', $('body')));
    console.log($('body').find('[ui\\:component]'));
    console.log($('body').filter('[ui\\:component]'));
    console.log($('body').find('*').filter('[ui\\:component]'));
});
</script>
</html>

【问题讨论】:

  • 注意:删除命名空间 ui: 似乎可以正常工作。但我不喜欢名字冲突.......
  • 在使用 Firefox 3.5 时,我可以使用 $("body *[ui\\:component]") 让它工作,但是我没有测试任何其他浏览器,所以即使它是 jQuery,我也不知道这是否会到处工作。虽然我知道不希望命名空间冲突,但浏览器和 js 往往对命名空间没有很好的支持。
  • @Thomas - 这类似于在问题中正常工作的代码$('[ui\\:component]')。选择器之所以有效,是因为它在可用时使用本机 querySelectorAll()(包括 Firefox 3.5)。但是.find().filter() 不起作用。
  • 谢谢。现在我已经删除了命名空间——这导致了不正确的 find();
  • @patrick - 有道理。所以很可能,除非是 IE8+、FF3.5+(至少根据 quirksmode.org),否则这些选择器将不起作用。

标签: jquery filter find


【解决方案1】:

我猜这是因为当你这样做时:

$('[ui\\:component]')

...Sizzle 将选择器传递给浏览器的 document.querySelectorAll() 方法(如果可用),有效地绕过了 Sizzle。

而当您执行 .find().filter() 时,正在使用 Sizzle。

所以我猜 Sizzle 不支持选择器中的某些内容,但 querySelectorAll() 支持。也许是:

我想你会发现:

document.querySelectorAll('[ui\\:component]').length

还有这个:

$('[ui\\:component]').length

...会给你类似的结果

编辑:

如果有帮助,连字符似乎可以正常工作。

$('body').find('[ui-component]').length

HTML

<ul ui-component="component2"></ul>

【讨论】:

    【解决方案2】:

    我发现使用 jQuery 做到这一点的最佳方法是编写自定义选择器:

    $.expr[':'].nsattr = function(obj, ix, meta) {
        var attr = meta[3];
    
        return (obj.getAttribute(attr) ? true : false);
    };
    

    然后你可以调用它

    $(document.body).find(':nsattr(ui:component)');
    $(document.body).children().filter(':nsattr(ui:component)');
    $(':nsattr(ui:component)', document.body);
    

    显然,这不是一种巧妙的方法。我怀疑这是 jQuery 的一个错误,可能值得您报告它。

    【讨论】:

    • 我和你在一起。我提交了一个错误 #7153
    • 这看起来不错,虽然我可能会使用原生的getAttribute() 而不是为每个元素创建一个 jQuery 对象。您还可以像这样使其更简洁:return !!obj.getAttribute(attr); 而不是 if() 语句。 :o)
    • @patrick 我已将其更改为 hasAttribute() - 好点。这也意味着我可以降低回报率...
    • hasAttribute() 方法会起作用,但it isn't supported in IE6/7 并不令人惊讶。 :o(
    • 呸,忘了:-( 三元是我的冗长解决方案——我发现!! 难以阅读。谢谢,帕特里克。
    【解决方案3】:

    改用&lt;div id="component"&gt;&lt;/div&gt;..

    【讨论】:

    • 不想让它成为一个 id。我希望根据它们的 ui:component 标签为特定项目分配功能。
    猜你喜欢
    • 1970-01-01
    • 2010-10-06
    • 2019-04-24
    • 2012-02-29
    • 2011-05-31
    • 1970-01-01
    • 2010-11-13
    • 2019-11-23
    • 2017-10-12
    相关资源
    最近更新 更多