9
votes

Comment puis-je dire si un nœud est en mémoire ou dans le DOM?

Je travaille beaucoup avec des nœuds avant qu'ils ne soient attachés à la page principale de la page principale; et je dois effectuer des travaux en fonction de la question de savoir si un nœud donné est contenu dans le document principal ou non.

Ma méthode actuelle consiste à marcher sur les parents, via: P>

if this.el$.closest("body").length > 0


6 commentaires

Eh bien, il variera d'ici à quel point je suis profondément dans l'arbre, je ne sais pas ce que j'ai en magasin pour ce projet, je pourrais faire une merde folle et être super plongée, les résultats vont varier :)


Il serait certainement intéressant de voir s'il y a un moyen plus approprié de tester cela, plutôt que de devoir marcher chaque fois l'ascendance du nœud à chaque fois


Qu'en est-il juste .parent () ? Je viens de faire un test rapide et un élément de mémoire n'avait aucun parent. Ou même plus rapide serait .parentnode de Javascript


@Mrobrian Je suis assez certain que lorsque vous appelez appendicchild sur un nœud en mémoire, il définira le parent du noeud annexé normalement. Si l'OP construit des arbres en mémoire, cela ne suffira pas.


Voir Cette question très similaire , je pense que la solution y aurait Être plus rapide


@Mrobrian: Vous êtes effectivement correct, la méthode ajoutée dans la solution liée est légèrement plus rapide et je l'ai ajoutée à mes tests d'exhaustivité. Merci pour les informations et le lien.


3 Réponses :


7
votes

Vous avez plusieurs options exécutées à plusieurs vitesses différentes. xxx

voir test de performance

Pour ce test, j'ai copié une énorme quantité de HTML à traverser, j'ai copié la source de l'une des pages JQuery dans un violon, en supprimant toutes les balises de script ne laissant que le corps et le HTML dans ENTRE >

J'ai mis à jour le test de performance pour utiliser la syntaxe correcte pour contient < / Strong> Comme le précédent était incorrect et toujours retourné vrai même si l'élément n'existait pas. Le coup revient maintenant true si l'élément existe, mais si vous spécifiez un sélecteur qui n'existe pas, il retournera false. xxx

J'ai également ajouté l'alternative suggérée mentionnée par Mrobrian dans les commentaires de la question qui est à nouveau légèrement plus rapide que celui de la contienne.

Nice One MROBRIAN .

EDIT < / strong>

voici le JSPERF test de performance avec tous les beaux graphiques.

Merci Felix Kling pour avoir repéré le problème et aider à résoudre les tests JSperf.

a ajouté plus de résultats de test des commentaires, celui-ci est vraiment bon: de
JSPERF Performance Test:
DOM-Tree-Test-Existe < / p>


8 commentaires

Impressionnant! $. Contient ressemble à la voie à suivre


Vous pourriez être intéressé par cette comparaison JSPERF: JSPERF.DOM-TREE-TEST


@Felixkling: J'ai essayé de configurer JSperf mais got TypeError: objet [objet objet] n'a pas de méthode 'comparéocumentposition'. lorsque vous essayez d'exécuter le code contient. Voici le lien vers le test d'échec: http://jsperf.com/closest-vs-contains Je ne sais pas comment le réparer. Alors j'ai eu recours à l'horloge dans le violon à la place :)


Le problème était que vous avez passé à JQuery Obsect à $. Contient , pas des nœuds Dom ...


@Felixkling: génial, j'ai corrigé les tests maintenant et les a ajoutés à la réponse, plus le mieux est d'info. Merci et bien repéré.


@Jonathan: Selon Ce test , la recherche d'identification pour les éléments ci-joints est encore plus rapide que < code> $. Contient en chrome. Et dans Firefox, en utilisant document.body.contains semble être beaucoup plus rapide que toute autre chose.


@Felixkling: Nice Trouvez, je vais aussi ajouter cela à la réponse. Très très bonne information.


document.body.contains est fou-rapide (3-4x plus rapide) sur safari 6 et iOS 6, ainsi que



4
votes

Vous pouvez attribuer un ID à l'élément puis la recherche de la recherche:

function in_tree(element) {
    if(!element || !element.parentNode) { // fail fast
        return false;
    }
    if(element.contains) {
        return document.body.contains(element);
    }
    var id = element.id || generateRandomId();
    element.id = id;
    return document.getElementById(id) !== null;
}


0 commentaires

6
votes

La réponse moderne et vanille est d'utiliser nœud .isconnected : xxx

(exemple directement à partir des documents MDN)


0 commentaires