Ich versuche zu bekommen:
document.createElement('div') //=> true
{tagName: 'foobar something'} //=> false
In meinen eigenen Skripten habe ich dies nur verwendet, da ich es nie tagName
als Eigenschaft brauchte :
if (!object.tagName) throw ...;
Für das zweite Objekt habe ich mir als schnelle Lösung Folgendes ausgedacht - was meistens funktioniert. ;)
Das Problem ist, dass es von Browsern abhängt, die schreibgeschützte Eigenschaften erzwingen, was nicht alle tun.
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;
}
}
Gibt es einen guten Ersatz?
javascript
dom
object
Jonathan Lonowski
quelle
quelle
Antworten:
Dies könnte von Interesse sein:
Es ist Teil des DOM, Level2 .
Update 2 : So habe ich es in meiner eigenen Bibliothek implementiert: (Der vorherige Code hat in Chrome nicht funktioniert, da Node und HTMLElement Funktionen anstelle des erwarteten Objekts sind. Dieser Code wird in FF3, IE7, Chrome 1 und Opera getestet 9).
quelle
function Fake() {}; Fake.prototype=document.createElement("div"); alert(new Fake() instanceof HTMLElement);
true
für[] instanceof HTMLElement
.HTMLElement
ist immer einfunction
,typeof
wirft Sie also von der Strecke und führt den zweiten Teil der Anweisung aus. Sie können es versuchen, wenn Sie möchteninstanceof Object
, da die Funktion eine Instanz von istObject
, oder einfach explizit prüfentypeof === "function"
, weilNode
undHTMLElement
beide native Objektfunktionen sind.isElement(0)
, wird 0 zurückgegeben, nicht false ... Warum ist das so und wie kann ich das verhindern?Der folgende IE8-kompatible, supereinfache Code funktioniert einwandfrei.
Die akzeptierte Antwort erkennt nicht alle Arten von HTML-Elementen. Beispielsweise werden SVG-Elemente nicht unterstützt. Im Gegensatz dazu funktioniert diese Antwort sowohl für HTML als auch für SVG.
Sehen Sie es hier in Aktion: https://jsfiddle.net/eLuhbu6r/
quelle
document
element nicht true zurückgibt (in allen Browsern). Wenn Sie es brauchen, sollten Sie versuchen:x instanceof Element || x instanceof HTMLDocument
Alle Lösungen oben und unten (einschließlich meiner Lösung) können falsch sein, insbesondere im IE. Es ist durchaus möglich, einige Objekte / Methoden / Eigenschaften (neu) zu definieren, um einen DOM-Knoten nachzuahmen, der den Test ungültig macht.
Normalerweise verwende ich den Test im Enten-Schreibstil: Ich teste speziell auf Dinge, die ich benutze. Wenn ich beispielsweise einen Knoten klonen möchte, teste ich ihn folgendermaßen:
Grundsätzlich ist es eine kleine Überprüfung der geistigen Gesundheit + der direkte Test für eine Methode (oder eine Eigenschaft), die ich verwenden möchte.
Der obige Test ist übrigens ein guter Test für DOM-Knoten in allen Browsern. Wenn Sie jedoch auf der sicheren Seite sein möchten, überprüfen Sie immer das Vorhandensein von Methoden und Eigenschaften und deren Typen.
BEARBEITEN: Der IE verwendet ActiveX-Objekte zur Darstellung von Knoten, sodass sich ihre Eigenschaften nicht als echtes JavaScript-Objekt verhalten. Beispiel:
während es "Funktion"
true
bzw. zurückgeben sollte. Die einzige Möglichkeit, Methoden zu testen, besteht darin, festzustellen, ob sie definiert sind.quelle
Sie können versuchen, es an einen echten DOM-Knoten anzuhängen ...
quelle
obj.cloneNode(false)
. UND hat keine Nebenwirkungen.Sie benötigen keine Hacks. Sie können einfach fragen, ob ein Element eine Instanz des DOM- Elements ist :
quelle
Wie wäre es mit Lo-Dash
_.isElement
?Und im Code:
quelle
Dies ist aus der schönen JavaScript-Bibliothek MooTools :
quelle
Mithilfe der hier gefundenen Stammerkennung können wir feststellen, ob z. B. alert ein Mitglied des Stamms des Objekts ist, der dann wahrscheinlich ein Fenster ist:
Um festzustellen, ob das Objekt das aktuelle Fenster ist, ist es noch einfacher:
Dies scheint günstiger zu sein als die Try / Catch-Lösung im Eröffnungsfaden.
Don P.
quelle
document.createElement()
DOM erstellt, aber nicht in DOM eingefügt wurden. Erstaunlich (: Dankealter Thread, aber hier ist eine aktualisierte Möglichkeit für Benutzer von ie8 und ff3.5 :
quelle
Ich schlage einen einfachen Weg vor, um zu testen, ob eine Variable ein DOM-Element ist
oder wie von HTMLGuy vorgeschlagen:
quelle
return typeof entity === 'object' && typeof entity.nodeType !== undefined;
object
s und / oder Poperties haben, kann dies manchmal sehr praktisch sein! Tx, @Roman// Tatsächlich verwende ich diese Inline eher nicht, aber manchmal ist es gut, diese Verknüpfungen für den Setup-Code zu haben
quelle
Dies könnte hilfreich sein: isDOM
Im obigen Code verwenden wir den Doppel-Negationsoperator , um den booleschen Wert des als Argument übergebenen Objekts abzurufen. Auf diese Weise stellen wir sicher, dass jeder in der bedingten Anweisung ausgewertete Ausdruck boolesch ist, wobei wir die Kurzschlussauswertung und damit die Funktion nutzen gibt
true
oder zurückfalse
quelle
undefined && window.spam("should bork")
bewertetspam
zum Beispiel niemals die gefälschte Funktion. Also nicht!!
nötig, glaube ich nicht. Können Sie einen [nicht-akademischen] Randfall liefern, bei dem es auf seine Verwendung ankommt?!!
Argument " wird nie benötigt" nicht gekauft haben ( und wenn Sie es nicht tun, bin ich neugierig, warum nicht ), können Sie diese Zeile bearbeitenreturn !!(obj && typeof obj === "object" && obj.nodeType === 1 && obj.nodeName);
und sie genauso funktionieren lassen.Sie können sehen, ob das betreffende Objekt oder der betreffende Knoten einen Zeichenfolgentyp zurückgibt.
quelle
typeof ({innerHTML: ""}).innerHTML === "string"
notANode.innerHTML = "<b>Whoops</b>";
und später diesen Code sein kontaminiertes Objekt an diesen Code weitergeben lässt. Defensiver Code === besserer Code, alle anderen Dinge sind gleich, und dies ist letztendlich nicht defensiv.Für diejenigen, die Angular verwenden:
https://docs.angularjs.org/api/ng/function/angular.isElement
quelle
function isElement(node) { return !!(node && (node.nodeName || (node.prop && node.attr && node.find))); }
Sieht ein bisschen aus wie @ finpingvins . Beachten Sie, dass es bestimmt, " ob eine Referenz ein DOM-Element (oder ein umschlossenes jQuery-Element) ist. "Ich denke, Prototyping ist keine sehr gute Lösung, aber vielleicht ist dies die schnellste: Definieren Sie diesen Codeblock;
als überprüfen Sie Ihre Objekte isDomElement-Eigenschaft:
Ich hoffe das hilft.
quelle
Laut mdn
Wir können
isElement
nach Prototyp implementieren . Hier ist mein Rat:quelle
Ich denke, Sie müssen einige Eigenschaften, die sich immer in einem dom-Element befinden, gründlich überprüfen, aber ihre Kombination wird sich höchstwahrscheinlich nicht in einem anderen Objekt befinden, wie z.
quelle
In Firefox können Sie die verwenden
instanceof Node
. DasNode
ist in DOM1 definiert .Aber das ist im IE nicht so einfach.
Sie können nur mithilfe der DOM-Funktion sicherstellen, dass es sich um ein DOM-Element handelt, und bei Ausnahmen abfangen. Es kann jedoch Nebenwirkungen haben (z. B. Ändern des internen Status / der Leistung / des Speicherverlusts des Objekts)
quelle
Vielleicht ist das eine Alternative? Getestet in Opera 11, FireFox 6, Internet Explorer 8, Safari 5 und Google Chrome 16.
Die Funktion lässt sich zB nicht täuschen
quelle
Folgendes habe ich herausgefunden:
Um die Leistung zu verbessern, habe ich eine selbstaufrufende Funktion erstellt, die die Funktionen des Browsers nur einmal testet und die entsprechende Funktion entsprechend zuweist.
Der erste Test sollte in den meisten modernen Browsern funktionieren und wurde hier bereits besprochen. Es wird nur getestet, ob das Element eine Instanz von ist
HTMLElement
. Sehr einfach.Der zweite ist der interessanteste. Dies ist seine Kernfunktionalität:
Es wird geprüft, ob el eine Instanz des Konstrukts ist, das es vorgibt zu sein. Dazu benötigen wir Zugriff auf den Konstruktor eines Elements. Deshalb testen wir dies in der if-Anweisung. IE7 zum Beispiel schlägt fehl, weil
(document.createElement("a")).constructor
esundefined
in IE7 ist.Das Problem bei diesem Ansatz ist, dass dies
document.createElement
nicht die schnellste Funktion ist und Ihre Anwendung leicht verlangsamen kann, wenn Sie viele Elemente damit testen. Um dies zu lösen, habe ich beschlossen, die Konstruktoren zwischenzuspeichern. Das ObjektElementConstructors
hat Knotennamen als Schlüssel mit den entsprechenden Konstruktoren als Werte. Wenn ein Konstruktor bereits zwischengespeichert ist, verwendet er ihn aus dem Cache. Andernfalls erstellt er das Element, speichert seinen Konstruktor für den zukünftigen Zugriff zwischen und testet ihn anschließend.Der dritte Test ist der unangenehme Fallback. Es wird getestet, ob el ein ist
object
, einenodeType
Eigenschaft auf gesetzt ist1
und eine Zeichenfolge alsnodeName
. Dies ist natürlich nicht sehr zuverlässig, aber die überwiegende Mehrheit der Benutzer sollte noch nicht einmal zurückgreifen.Dies ist der zuverlässigste Ansatz, den ich mir ausgedacht habe, während die Leistung so hoch wie möglich gehalten wurde.
quelle
Testen Sie, ob es
obj
von Node erbt .Der Knoten ist eine grundlegende Schnittstelle, von der HTMLElement und Text erben.
quelle
Unterscheiden Sie ein rohes js-Objekt von einem HTMLElement
verwenden:
// ODER
verwenden:
o={}; o.is("HTML") // false o=document.body; o.is("HTML") // true
quelle
Hier ist ein Trick mit jQuery
also in eine Funktion setzen:
quelle
elem.nodeType === 1
dies intern. Warum nicht den Anrufaufwand und die jQuery-Abhängigkeit speichern und Ihre isElement-Funktion dies selbst tun lassen?Nicht auf dieses oder irgendetwas zu hämmern, sondern auf ES5-kompatible Browser, warum nicht einfach:
Wird nicht auf TextNodes arbeiten und nicht sicher Schatten DOM oder DocumentFragments usw. aber werden fast alle HTML - Tag - Elemente arbeiten.
quelle
Dies funktioniert für fast jeden Browser. (Keine Unterscheidung zwischen Elementen und Knoten hier)
quelle
Als absolut richtige Methode ist check target ein echter HTML-Element-Primärcode:
quelle
Jeder DOMElement.constructor gibt die Funktion HTML ... Element () oder [Object HTML ... Element] zurück, also ...
quelle
Ich habe eine spezielle Möglichkeit, dies zu tun, die in den Antworten noch nicht erwähnt wurde.
Meine Lösung basiert auf vier Tests. Wenn das Objekt alle vier übergibt, ist es ein Element:
Das Objekt ist nicht null.
Das Objekt hat eine Methode namens "appendChild".
Die Methode "appendChild" wurde von der Node- Klasse geerbt und ist nicht nur eine Betrüger-Methode (eine vom Benutzer erstellte Eigenschaft mit identischem Namen).
Das Objekt ist vom Knotentyp 1 (Element). Objekte, die Methoden von der Node- Klasse erben, sind immer Nodes, aber nicht unbedingt Elements.
F: Wie überprüfe ich, ob eine bestimmte Eigenschaft vererbt wurde und nicht nur ein Betrüger ist?
A: Ein einfacher Test, um festzustellen, ob eine Methode wirklich von Node geerbt wurde, besteht darin, zunächst zu überprüfen, ob die Eigenschaft einen Typ von "Objekt" oder "Funktion" hat. Konvertieren Sie anschließend die Eigenschaft in eine Zeichenfolge und prüfen Sie, ob das Ergebnis den Text "[Native Code]" enthält. Wenn das Ergebnis ungefähr so aussieht:
Dann wurde die Methode vom Node-Objekt geerbt. Siehe https://davidwalsh.name/detect-native-function
Und schließlich, wenn alle Tests zusammengeführt werden, lautet die Lösung:
quelle
Dies prüft, ob es sich um ein jQuery- oder JavaScript-DOM-Element handelt
quelle
Die einzige Möglichkeit, um sicherzustellen, dass Sie ein tatsächliches HTMLEement und nicht nur ein Objekt mit denselben Eigenschaften wie ein HTML-Element überprüfen, besteht darin, festzustellen, ob es von Node erbt, da es unmöglich ist, einen neuen Node () in JavaScript zu erstellen. (es sei denn, die native Knotenfunktion wird überschrieben, aber dann haben Sie kein Glück). So:
quelle