J'essaye d'obtenir:
document.createElement('div') //=> true
{tagName: 'foobar something'} //=> false
Dans mes propres scripts, j'utilisais juste ceci car je n'avais jamais besoin tagName
d'une propriété:
if (!object.tagName) throw ...;
Donc, pour le deuxième objet, j'ai trouvé ce qui suit comme une solution rapide - qui fonctionne principalement. ;)
Le problème est que cela dépend des navigateurs appliquant des propriétés en lecture seule, ce qui n'est pas le cas de tous.
function isDOM(obj) {
var tag = obj.tagName;
try {
obj.tagName = ''; // Read-only for DOM, should throw exception
obj.tagName = tag; // Restore for normal objects
return false;
} catch (e) {
return true;
}
}
Y a-t-il un bon substitut?
javascript
dom
object
Jonathan Lonowski
la source
la source
Réponses:
Cela pourrait être intéressant:
Cela fait partie du DOM, Level2 .
Mise à jour 2 : voici comment je l'ai implémenté dans ma propre bibliothèque: (le code précédent ne fonctionnait pas dans Chrome, car Node et HTMLElement sont des fonctions au lieu de l'objet attendu. Ce code est testé dans FF3, IE7, Chrome 1 et Opera 9).
la source
function Fake() {}; Fake.prototype=document.createElement("div"); alert(new Fake() instanceof HTMLElement);
true
pour[] instanceof HTMLElement
.HTMLElement
est toujours unfunction
, donctypeof
vous jettera hors de la piste et exécutera la deuxième partie de l'instruction. Vous pouvez essayer si vous le souhaitezinstanceof Object
, car la fonction sera une instance deObject
, ou simplement vérifier explicitementtypeof === "function"
, carNode
etHTMLElement
sont toutes deux des fonctions d'objet natif.isElement(0)
, il retourne 0, pas faux ... Pourquoi cela, et comment puis-je empêcher cela?Le code super-simple compatible IE8 suivant fonctionne parfaitement.
La réponse acceptée ne détecte pas tous les types d'éléments HTML. Par exemple, les éléments SVG ne sont pas pris en charge. En revanche, cette réponse fonctionne aussi bien pour HTML que SVG.
Voyez-le en action ici: https://jsfiddle.net/eLuhbu6r/
la source
document
élément (dans tous les navigateurs). si vous en avez besoin, vous devriez essayer:x instanceof Element || x instanceof HTMLDocument
Toutes les solutions ci-dessus et ci-dessous (ma solution y compris) souffrent de la possibilité d'être incorrectes, en particulier sur IE - il est tout à fait possible de (re) définir certains objets / méthodes / propriétés pour imiter un nœud DOM rendant le test invalide.
Donc, d'habitude, j'utilise les tests de type canard: je teste spécifiquement pour les choses que j'utilise. Par exemple, si je veux cloner un nœud, je le teste comme ceci:
Fondamentalement, c'est un petit test de santé mentale + le test direct d'une méthode (ou d'une propriété) que je prévois d'utiliser.
Soit dit en passant, le test ci-dessus est un bon test pour les nœuds DOM sur tous les navigateurs. Mais si vous voulez être prudent, vérifiez toujours la présence de méthodes et de propriétés et vérifiez leurs types.
EDIT: IE utilise des objets ActiveX pour représenter les nœuds, de sorte que leurs propriétés ne se comportent pas comme de véritables objets JavaScript, par exemple:
alors qu'il devrait retourner respectivement "fonction" et
true
. La seule façon de tester les méthodes est de voir si elles sont définies.la source
Vous pouvez essayer de l'ajouter à un véritable noeud DOM ...
la source
obj.cloneNode(false)
. ET n'a aucun effet secondaire.Pas besoin de hacks, vous pouvez simplement demander si un élément est une instance de l' élément DOM :
la source
Qu'en est-il de Lo-Dash
_.isElement
?Et dans le code:
la source
C'est de la belle bibliothèque JavaScript MooTools :
la source
En utilisant la détection de racine trouvée ici , nous pouvons déterminer si, par exemple, alert est un membre de la racine de l'objet, qui est alors susceptible d'être une fenêtre:
Pour déterminer si l'objet est la fenêtre actuelle est encore plus simple:
Cela semble être moins cher que la solution try / catch dans le thread d'ouverture.
Don P
la source
document.createElement()
mais non insérés dans DOM aussi. Incroyable (: Merciancien thread, mais voici une possibilité mise à jour pour les utilisateurs ie8 et ff3.5 :
la source
Je suggère un moyen simple de tester si une variable est un élément DOM
ou comme HTMLGuy l'a suggéré:
la source
return typeof entity === 'object' && typeof entity.nodeType !== undefined;
object
s et / ou propriétés, cela peut être très pratique! Tx, @Roman// En fait, je suis plus susceptible de les utiliser en ligne, mais parfois il est bon d'avoir ces raccourcis pour le code de configuration
la source
Cela pourrait être utile: isDOM
Dans le code ci-dessus, nous utilisons l' opérateur de double négation pour obtenir la valeur booléenne de l'objet passé en argument, de cette façon nous nous assurons que chaque expression évaluée dans l'instruction conditionnelle soit booléenne, en profitant de l' évaluation de court-circuit , donc la fonction retourne
true
oufalse
la source
undefined && window.spam("should bork")
n'évalue jamais la faussespam
fonction, par exemple. Donc pas!!
nécessaire, je ne crois pas. Cela, pouvez-vous fournir un cas de pointe [non académique] où son utilisation est importante?!!
argument " n'est jamais nécessaire" ( et si vous ne l'avez pas, je suis curieux de savoir pourquoi ), vous pouvez modifier cette lignereturn !!(obj && typeof obj === "object" && obj.nodeType === 1 && obj.nodeName);
et la faire fonctionner de la même manière.Vous pouvez voir si l'objet ou le nœud en question renvoie un type de chaîne.
la source
typeof ({innerHTML: ""}).innerHTML === "string"
notANode.innerHTML = "<b>Whoops</b>";
, puis plus tard, ce code passe son obj contaminé à ce code. Code défensif === meilleur code, toutes choses égales par ailleurs, et ce n'est finalement pas défensif.Pour ceux qui utilisent Angular:
https://docs.angularjs.org/api/ng/function/angular.isElement
la source
function isElement(node) { return !!(node && (node.nodeName || (node.prop && node.attr && node.find))); }
ressemble un peu à @ finpingvin . Notez qu'il détermine " si une référence est un élément DOM (ou un élément jQueryJe pense que le prototypage n'est pas une très bonne solution, mais c'est peut-être la plus rapide: définir ce bloc de code;
que de vérifier la propriété isDomElement de vos objets:
J'espère que ça aide.
la source
Selon mdn
Nous pouvons l'implémenter
isElement
par prototype. Voici mon conseil:la source
Je pense que ce que vous devez faire est de vérifier minutieusement certaines propriétés qui seront toujours dans un élément dom, mais leur combinaison ne sera probablement pas dans un autre objet, comme ceci:
la source
Dans Firefox, vous pouvez utiliser le
instanceof Node
. CelaNode
est défini dans DOM1 .Mais ce n'est pas si simple dans IE.
Vous ne pouvez vous assurer qu'il s'agit bien d'un élément DOM qu'en utilisant la fonction DOM et intercepter s'il y a une exception. Cependant, cela peut avoir un effet secondaire (par exemple, changer l'état interne de l'objet / les performances / la fuite de mémoire)
la source
C'est peut-être une alternative? Testé dans Opera 11, FireFox 6, Internet Explorer 8, Safari 5 et Google Chrome 16.
La fonction ne sera pas dupée par exemple par ceci
la source
Voici ce que j'ai compris:
Pour améliorer les performances, j'ai créé une fonction auto-invoquante qui teste les capacités du navigateur une seule fois et attribue la fonction appropriée en conséquence.
Le premier test devrait fonctionner dans la plupart des navigateurs modernes et a déjà été discuté ici. Il teste simplement si l'élément est une instance de
HTMLElement
. Très simple.Le second est le plus intéressant. Voici sa fonctionnalité principale:
Il teste si el est une instance du constructeur qu'il prétend être. Pour ce faire, nous devons avoir accès au constructeur d'un élément. C'est pourquoi nous testons cela dans la déclaration if. IE7 par exemple échoue, car
(document.createElement("a")).constructor
estundefined
dans IE7.Le problème avec cette approche est que ce
document.createElement
n'est vraiment pas la fonction la plus rapide et pourrait facilement ralentir votre application si vous testez beaucoup d'éléments avec elle. Pour résoudre ce problème, j'ai décidé de mettre en cache les constructeurs. L'objetElementConstructors
a nodeNames comme clés avec ses constructeurs correspondants comme valeurs. Si un constructeur est déjà mis en cache, il l'utilise à partir du cache, sinon il crée l'élément, met en cache son constructeur pour un accès futur, puis le teste.Le troisième test est le repli désagréable. Il teste si el est an
object
, a unenodeType
propriété définie sur1
et une chaîne asnodeName
. Bien sûr, ce n'est pas très fiable, mais la grande majorité des utilisateurs ne devraient même pas se replier jusqu'à présent.C'est l'approche la plus fiable que j'ai trouvée tout en maintenant des performances aussi élevées que possible.
la source
Testez si
obj
hérite de Node .Node est une interface de base dont HTMLElement et Text héritent.
la source
différencier un objet js brut d'un HTMLElement
utilisation:
// OU
utilisation:
o={}; o.is("HTML") // false o=document.body; o.is("HTML") // true
la source
voici une astuce en utilisant jQuery
donc le mettre dans une fonction:
la source
elem.nodeType === 1
alors pourquoi ne pas enregistrer la surcharge d'appel et la dépendance jQuery et demander à votre fonction isElement de le faire elle-même?Ne pas marteler cela ou quoi que ce soit, mais pour les navigateurs compatibles ES5, pourquoi pas seulement:
Ne fonctionnera pas sur et pas sûr de nœuds texte au sujet de l' ombre DOM ou DocumentFragments etc. , mais va travailler sur presque tous les éléments de balise HTML.
la source
Cela fonctionnera pour presque tous les navigateurs. (Pas de distinction entre les éléments et les nœuds ici)
la source
Une méthode à droite absolue, check target est un vrai code primaire d'élément html:
la source
Chaque DOMElement.constructor renvoie la fonction HTML ... Element () ou [Object HTML ... Element] donc ...
la source
J'ai une façon spéciale de le faire qui n'a pas encore été mentionnée dans les réponses.
Ma solution est basée sur quatre tests. Si l'objet passe tous les quatre, alors c'est un élément:
L'objet n'est pas nul.
L'objet a une méthode appelée "appendChild".
La méthode "appendChild" a été héritée de la classe Node , et n'est pas seulement une méthode imposteur (une propriété créée par l'utilisateur avec un nom identique).
L'objet est de type noeud 1 (élément). Objets qui héritent des méthodes du classe Node sont toujours des Nodes, mais pas nécessairement des Elements.
Q: Comment puis-je vérifier si une propriété donnée est héritée et n'est pas seulement un imposteur?
R: Un test simple pour voir si une méthode a vraiment été héritée de Node consiste à vérifier d'abord que la propriété a un type "d'objet" ou de "fonction". Ensuite, convertissez la propriété en chaîne et vérifiez si le résultat contient le texte "[Code natif]". Si le résultat ressemble à ceci:
Ensuite, la méthode a été héritée de l'objet Node. Voir https://davidwalsh.name/detect-native-function
Et enfin, réunissant tous les tests, la solution est:
la source
Cela vérifiera même s'il s'agit d'un élément DOM jQuery ou JavaScript
la source
La seule façon de garantir que vous vérifiez un HTMLEement réel, et pas seulement un objet avec les mêmes propriétés qu'un élément HTML, est de déterminer s'il hérite de Node, car il est impossible de créer un nouveau Node () en JavaScript. (sauf si la fonction Node native est écrasée, mais vous n'avez pas de chance). Alors:
la source