2010-10-11 4 views
4

J'ai essayé plusieurs façons de filtrer la découverte de nœuds spécifiques dans mon code HTML.JQuery: Recherche/Filtrage sur les attributs dans le contexte

Voici quelques exemples html:

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

Je suis en mesure de faire correspondre avec succès des articles en faisant un filtre simple:

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

Cependant, quand je commence à filtrer en fonction d'un parent nœud, il commence à échouer sur moi. J'ai essayé:

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

Qu'est-ce que je fais mal ici? Au début, je pensais que cela pourrait être l'espace de noms, mais l'ajouter à la doc html ou le corps ne semble pas faire quelque chose de significatif. Aide a beaucoup apprécié

SOURCE complète ci-dessous:

<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> 
+0

REMARQUE: supprimer l'espace de nommage ui: semble le faire fonctionner. Mais je n'aime pas les collisions de noms ....... – ansiart

+1

Lors de l'utilisation de Firefox 3.5, j'ai pu le faire fonctionner en utilisant $ ("body * [ui \\: component]") ', mais je n'ai pas Ne teste pas d'autres navigateurs, donc même si c'est jQuery, je ne sais pas si ça marchera partout. Et bien que je comprenne ne pas vouloir des collisions d'espace de noms, les navigateurs et js ont tendance à ne pas avoir un grand soutien pour les espaces de noms. – Thomas

+1

@Thomas - Ce serait similaire au code '$ ('[ui \\: component]')' qui fonctionnait correctement dans la question. Le sélecteur fonctionne car il utilise 'querySelectorAll 'natif (si disponible) (qui inclurait Firefox 3.5). Mais les '.find()' et '.filter()' ne fonctionnent pas. – user113716

Répondre

2

Je devine que c'est parce que quand vous faites:

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

... Sizzle est passer le sélecteur à la méthode document.querySelectorAll() du navigateur (si disponible), contournant efficacement Sizzle.

Alors que lorsque vous faites .find() ou .filter(), Sizzle est utilisé.

Donc je suppose que quelque chose dans le sélecteur n'est pas supporté par Sizzle, mais par querySelectorAll(). Peut-être le :.

Je pense que vous constaterez que ceci:

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

et ceci:

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

... vous donnera des résultats similaires

EDIT:

Si ça aide, un trait d'union semble fonctionner correctement.

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

HTML

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

Essayez <div id="component"></div> à la place ..

+0

Ne cherche pas à en faire un identifiant. Je cherche à assigner des fonctionnalités à des éléments spécifiques en fonction de leur balise ui: component. – ansiart

1

La meilleure façon que j'ai trouvé le faire en utilisant jQuery est d'écrire un sélecteur personnalisé:

$.expr[':'].nsattr = function(obj, ix, meta) { 
    var attr = meta[3]; 

    return (obj.getAttribute(attr) ? true : false); 
}; 

Vous pouvez ensuite appeler cela avec

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

De toute évidence, ce n'est pas une t façon de le faire. Je soupçonne que c'est un bug avec jQuery et il pourrait être utile de le signaler comme tel.

+0

Je suis avec vous. J'ai déposé un bogue # 7153 – ansiart

+0

Cela semble bien, même si j'utiliserais probablement le 'getAttribute()' natif au lieu de créer un objet jQuery pour chaque élément. Vous pouvez aussi le rendre un peu plus concis comme ceci: 'return !! obj.getAttribute (attr);' à la place de l'instruction 'if()'. : o) – user113716

+0

@patrick Je l'ai changé pour 'hasAttribute()' - bon point. Cela signifie également que je peux affiner le retour vers le bas ... – lonesomeday

Questions connexes