Tester si un sélecteur correspond à un élément donné
Est-il un moyen de tester si un sélecteur pourrait correspondre à un Élément du DOM? De préférence, sans l'utilisation d'une bibliothèque externe comme Grésillement. C'est une bibliothèque, et je tiens à minimiser la quantité de plugins tiers requise pour le "core" de la bibliothèque. S'il finit par exiger Grésillement je vais juste ajouter que comme un plugin à la bibliothèque pour ceux qui veulent la fonctionnalité qu'il permettrait.
Par exemple, je serais capable de faire quelque chose comme:
var element = <input name="el" />
matches("input[name=el]", element) == true
MODIFIER: Après y avoir réfléchi plus, j'ai trouvé une solution, cette technique fonctionne, mais il ne semble pas optimale en termes d'efficacité:
function matchesSelector(selector, element) {
var nodeList = document.querySelectorAll(selector);
for ( var e in nodeList ) {
return nodeList[e] === element;
}
return false;
}
Fondamentalement, la fonction des requêtes de l'ensemble du document avec le sélecteur de donnée, puis il parcourt la nodeList. Si l'élément est dans le nodeList, puis elle retourne true, et si elle n'est pas elle retourne la valeur false.
Si quelqu'un peut venir avec une réponse plus efficace, je serais heureux de marquer leur réponse la réponse.
MODIFIER: Flavius Stef m'a orienté vers un navigateur spécifique solution pour Firefox 3.6+, mozMatchesSelector. J'ai aussi trouvé l'équivalent pour google Chrome (version de compatibilité inconnu, et il peut ou peut ne pas fonctionner sur Safari ou d'autres navigateurs webkit): webkitMatchesSelector
, qui est essentiellement la même que celle de Firefox mise en œuvre. Je n'ai pas trouvé d'implémentation native pour les navigateurs IE encore.
Pour l'exemple ci-dessus, l'utilisation serait:
element.(moz|webkit)MatchesSelector("input[name=el]")
Il semble que le W3C a également été abordé dans l'API de Sélecteurs de Niveau 2 (encore un projet en ce moment) de la spécification. matchesSelector
d'une méthode sur les Éléments DOM, une fois approuvées.
W3C Utilisation: element.matchesSelector(selector)
Depuis cette spécification est encore qu'un projet et il y a un décalage de temps avant que les navigateurs populaires de mettre en œuvre les méthodes une fois qu'il devient la norme, il peut être un certain temps jusqu'à ce que réellement utilisable. La bonne nouvelle est que si vous utilisez l'un des populaires cadres, les chances sont qu'ils probablement mettre en œuvre cette fonctionnalité pour vous, sans avoir à vous soucier de la compatibilité du navigateur. Bien que cela n'aide pas ceux d'entre nous qui ne peuvent pas inclure des bibliothèques tierces.
Des cadres ou des bibliothèques de mise en œuvre de cette fonctionnalité:
http://www.prototypejs.org/api/element/match
http://developer.yahoo.com/yui/docs/YAHOO.util.Selector.html
http://docs.jquery.com/Traversing/is
http://extjs.com/deploy/dev/docs/output/Ext.DomQuery.html#Ext.DomQuery-methods
http://base2.googlecode.com/svn/doc/base2.html#/doc/!base2.DOM.De l'élément.matchesSelector
http://wiki.github.com/jeresig/sizzle/
- Je ne peux pas imaginer comment vous pouvez le faire - en supposant que vous souhaitez prendre en charge une large gamme de sélecteurs, ou tous les CSS2 ou 3 sélecteurs - sans la terrible proximité de réimplanter le Grésillement de toute façon. Parce que c'est déjà optimisé et débogué, pourquoi ne pas l'utiliser?
- J'espérais qu'il y a un moyen de le faire "nativement" avec la construction dans le sélecteur de moteur dans les navigateurs modernes (via querySelector et querySelectorAll). Si non, comme je l'ai dit, je vais recourir à l'aide d'une bibliothèque, mais de déléguer cette fonction à un plugin Grésillement n'est pas nécessaire pour mon "cœur" de la bibliothèque.
- Firefox 3.6 a Noeud.mozMatchesSelector(): developer.mozilla.org/en/DOM/Node.mozMatchesSelector
- Stef: Il ne ressemble pas à n'importe quel navigateur croix de chemin à faire encore, mais merci pour le lien, je l'ai suivi du W3C niveau 2 cahier des charges qu'ils ont abordé, de sorte qu'il est seulement une question de la spécification en cours de finalisation et les navigateurs de la mettre en œuvre. Si vous ajoutez plus d'informations à propos de l'inclusion de la matchesSelector méthode dans les "Sélecteurs W3C API de Niveau 2 (Première version)" dans votre réponse, je vais le marquer comme réponse. Si non, je vais le monter dans mon post.
- À l'aide de Modernizr, vous pouvez le faire
Modernizr.prefixed('MatchesSelector,element)
pour obtenir une fonction (si elle existe) avec les bonnes (ou pas) vendeur préfixe, qui peut ensuite être utilisé commefn && fn(selector)
. - (moz|webkit|o|ms)matchesSelector désormais pris en charge sur tous les principaux navigateurs de bureau, comme par developer.mozilla.org/en-US/docs/Web/API/...
Vous devez vous connecter pour publier un commentaire.
Pour le bénéfice de ceux qui visitent cette page après lo de ces nombreuses années, cette fonctionnalité est désormais mis en œuvre dans tous les navigateurs modernes comme
element.matches
sans vendeur préfixe (sauf pourms
pour MS navigateurs autres qu'Edge 15, etwebkit
pour Android/KitKat). Voir http://caniuse.com/matchesselector.document.body.matches('.question-page')
Pour de meilleures performances, utilisez le navigateur implémentations (
(moz|webkit|o|ms)matchesSelector
) lorsque cela est possible. Lorsque vous ne pouvez pas le faire, voici un manuel de mise en œuvre.Une affaire importante à considérer est de tester les sélecteurs d'éléments qui n'ont pas joint au document.
Ici est une approche qui gère cette situation. Si il s'avère que la la
element
en question n'est pas joint au document, ramper jusqu'à l'arbre le plus grand ancêtre (le dernier non-nullparentNode
) et déposez-la dans unDocumentFragment
. Puis, à partir deDocumentFragment
appelquerySelectorAll
et de voir si le votreelement
est dans laNodeList
.Voici le code.
Le document
Voici la structure d'un document, nous allons travailler avec. Nous allons attraper la
.element
et de vérifier si elle correspond à la sélecteursli
et.container *
.Recherche avec
document.querySelectorAll
Ici est un
matchesSelector
fonction qui utilisedocument.querySelectorAll
.Cela fonctionne tant que l'élément est dans la
document
.Cependant, il échoue si l'élément est retiré de la
document
.De la recherche dans une
DocumentFragment
Le correctif nécessite une recherche que sous-arbre qui
element
arrive à être dans. Voici une mise à jour de fonction nomméematchesSelector2
.Maintenant, nous voyons que matchesSelector2 fonctionne même si l'élément est dans un sous-arbre qui est détachée du document.
Vous pouvez voir ce travail à jsfiddle.
Mettre tous ensemble
Voici la mise en œuvre finale, je suis venu avec:
Une remarque importante est que jQuery est mise en œuvre est beaucoup plus rapide. La première optimisation je veux le regarder dans est d'éviter l'exploration jusqu'à l'arbre, si nous n'avez pas à. Pour ce faire, vous pouvez consulter la droite-la majeure partie de la sélection et de vérifier si cela correspond à l'élément. Toutefois, méfiez-vous que si le sélecteur est en fait plusieurs sélecteurs séparés par des virgules, alors vous aurez à tester chacun d'eux. À ce stade, vous êtes en train de construire un sélecteur CSS de l'analyseur, de sorte que vous pourriez aussi bien utiliser une bibliothèque.
En l'absence de
xMatchesSelector
, je suis en train de penser à essayer d'ajouter un style à la demande de sélection d'unstyleSheet
objet, avec quelques arbitraire de la règle et de la valeur qui n'est pas susceptible d'être déjà en cours d'utilisation. Ensuite, vérifiez lecomputed/currentStyle
de l'élément pour voir si elle a hérité de l'ajout de la règle CSS. Quelque chose comme ceci pour IE:Il y a probablement un sac à main plein de gotcha avec cette méthode. Probablement le meilleur pour trouver quelque obscure propriétaire de la règle CSS qui est moins susceptible d'avoir un effet visuel que
z-index
, mais depuis qu'il est retiré presque immédiatement après qu'il est défini, un bref scintillement devrait être le seul effet secondaire si ce. Également l'un des plus obscurs de la règle sera moins susceptible d'être remplacé par un autre, plus précis sélecteur d'attribut de style de règles, ou autres !règles importantes (si IE supporte même que). De toute façon, vaut la peine d'essayer au moins.L'API de sélecteurs W3C (http://www.w3.org/TR/selectors-api/) spécifie
document.querySelectorAll()
. Ce n'est pas pris en charge sur tous les navigateurs, de sorte que vous auriez à google ceux qui ne les soutiennent: http://www.google.com/search?q=browsers+exécution+sélecteur+apiJe fais face à ce problème aujourd'hui. J'ai à l'appui de IE8 avec Javascript natif, qui présente un curieux défi: IE8 prend en charge les deux querySelector et querySelectorAll, mais pas matchesSelector. Si votre situation est la même, ici est une option à considérer:
Lorsque vous avez remis le nœud DOM et d'un sélecteur, faites une copie du nœud ainsi que son parent. Cela permettra de préserver l'ensemble de leurs attributs, mais ne sera pas faire des copies de leurs enfants respectifs.
Joindre la cloné nœud à la cloné parent. L'utilisation de querySelector sur la cloné parent -- la seule chose qu'il doit rechercher est le seul nœud enfant il a donc, ce processus est la constante de temps. Il sera de retour de l'enfant du nœud ou il ne sera pas.
Que j'avais de ressembler à quelque chose comme ceci:
Il peut être intéressant de créer une chaîne complète de profondes copié parents tout le chemin jusqu'à la racine de nœud et l'interrogation de l' (la plupart du temps vide) mannequin racine si vous souhaitez être en mesure de tester votre nœud de la relation de ses ancêtres.
Sur le dessus de ma tête, je ne suis pas sûr de ce que la portion de sélecteurs ce serait travailler pour, mais je pense que
il ferait bien de tout cela n'a pas à s'inquiéter de l'testé nœud enfants. YMMV.
-- EDIT --
J'ai décidé d'écrire la fonction de copie de tout à partir du nœud d'être testé à la racine. À l'aide de ce que beaucoup plus les sélecteurs sont aptes à l'emploi. (Rien liées à des frères et sœurs, si.)
Je serais la bienvenue à un expert pour expliquer quels types de sélecteurs il y a que ce ne serait pas la couverture!
Les navigateurs modernes permettent de le faire avec la
document.querySelectorAll
fonction.http://www.w3.org/TR/selectors-api/
Suffit d'utiliser un id pour votre élément? HTML-les Identifiants d'être unique...