Estoy tratando de obtener:
document.createElement('div') //=> true
{tagName: 'foobar something'} //=> false
En mis propios scripts, solía usar esto ya que nunca lo necesitaba tagName
como propiedad:
if (!object.tagName) throw ...;
Entonces, para el segundo objeto, se me ocurrió lo siguiente como una solución rápida, que funciona principalmente. ;)
El problema es que depende de que los navegadores apliquen propiedades de solo lectura, lo que no todos hacen.
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;
}
}
¿Hay un buen sustituto?
javascript
dom
object
Jonathan Lonowski
fuente
fuente
Respuestas:
Esto puede ser de interés:
Es parte del DOM, Nivel2 .
Actualización 2 : así es como lo implementé en mi propia biblioteca: (el código anterior no funcionaba en Chrome, porque Node y HTMLElement son funciones en lugar del objeto esperado. Este código se prueba en FF3, IE7, Chrome 1 y Opera 9)
fuente
function Fake() {}; Fake.prototype=document.createElement("div"); alert(new Fake() instanceof HTMLElement);
true
para[] instanceof HTMLElement
.HTMLElement
siempre es unfunction
, asítypeof
que lo sacará de la pista y ejecutará la segunda parte de la declaración. Puede intentarlo si lo deseainstanceof Object
, porque la función será una instancia deObject
, o simplemente comprobará explícitamentetypeof === "function"
, porqueNode
yHTMLElement
son funciones de objeto nativas.isElement(0)
, devuelve 0, no falso ... ¿Por qué es eso y cómo puedo evitarlo?El siguiente código súper simple compatible con IE8 funciona perfectamente.
La respuesta aceptada no detecta todos los tipos de elementos HTML. Por ejemplo, los elementos SVG no son compatibles. Por el contrario, esta respuesta funciona tanto para HTML como para SVG.
Véalo en acción aquí: https://jsfiddle.net/eLuhbu6r/
fuente
document
elemento (en todos los navegadores). si lo necesita, debe intentar:x instanceof Element || x instanceof HTMLDocument
Todas las soluciones anteriores y posteriores (incluida mi solución) tienen la posibilidad de ser incorrectas, especialmente en IE: es bastante posible (re) definir algunos objetos / métodos / propiedades para imitar un nodo DOM que invalida la prueba.
Por lo general, utilizo la prueba de estilo de escritura de pato: pruebo específicamente las cosas que uso. Por ejemplo, si quiero clonar un nodo, lo pruebo así:
Básicamente es un pequeño control de cordura + la prueba directa para un método (o una propiedad) que planeo usar.
Por cierto, la prueba anterior es una buena prueba para los nodos DOM en todos los navegadores. Pero si desea estar seguro, siempre verifique la presencia de métodos y propiedades y verifique sus tipos.
EDITAR: IE usa objetos ActiveX para representar nodos, por lo que sus propiedades no se comportan como un verdadero objeto JavaScript, por ejemplo:
mientras que debería devolver "función" y
true
respectivamente. La única forma de probar los métodos es ver si están definidos.fuente
Podría intentar agregarlo a un nodo DOM real ...
fuente
obj.cloneNode(false)
. Y no tiene efectos secundarios.No es necesario piratear, solo puede preguntar si un elemento es una instancia del elemento DOM :
fuente
¿Qué hay de Lo-Dash's
_.isElement
?Y en el código:
fuente
Esto es de la encantadora biblioteca de JavaScript MooTools :
fuente
Al usar la detección de raíz que se encuentra aquí , podemos determinar si, por ejemplo, alert es un miembro de la raíz del objeto, que probablemente sea una ventana:
Para determinar si el objeto es la ventana actual es aún más simple:
Esto parece ser menos costoso que la solución try / catch en el hilo de apertura.
Don P
fuente
document.createElement()
de DOM, pero no insertados. Asombroso (: Graciashilo antiguo, pero aquí hay una posibilidad actualizada para usuarios de ie8 y ff3.5 :
fuente
Sugiero una forma simple de probar si una variable es un elemento DOM
o como HTMLGuy sugirió:
fuente
return typeof entity === 'object' && typeof entity.nodeType !== undefined;
object
propiedad y / o propiedad, ¡esto puede ser muy útil! Tx, @Roman// De hecho, es más probable que use estos en línea, pero a veces es bueno tener estos atajos para el código de configuración
fuente
Esto podría ser útil: isDOM
En el código anterior, usamos el operador de doble negación para obtener el valor booleano del objeto pasado como argumento, de esta manera nos aseguramos de que cada expresión evaluada en la declaración condicional sea booleana, aprovechando la evaluación de cortocircuito , por lo tanto, la función vuelve
true
ofalse
fuente
undefined && window.spam("should bork")
nunca evalúa laspam
función falsa , por ejemplo. Así que no hace!!
falta, no lo creo. Eso, ¿puede proporcionar un caso límite [no académico] donde su uso es importante?!!
argumento "nunca es necesario" ( y si no lo hace, tengo curiosidad por qué no ), puede editar esa líneareturn !!(obj && typeof obj === "object" && obj.nodeType === 1 && obj.nodeName);
y hacer que funcione igual.Puede ver si el objeto o nodo en cuestión devuelve un tipo de cadena.
fuente
typeof ({innerHTML: ""}).innerHTML === "string"
notANode.innerHTML = "<b>Whoops</b>";
, y luego que ese código pase su obj contaminado a este código. Código defensivo === mejor código, todas las demás cosas iguales, y esto finalmente no es defensivoPara los que usan Angular:
https://docs.angularjs.org/api/ng/function/angular.isElement
fuente
function isElement(node) { return !!(node && (node.nodeName || (node.prop && node.attr && node.find))); }
parece un poco a @ finpingvin . Nota que es determinar " si una referencia es un elemento DOM (o elemento envuelto jQuery). "Creo que la creación de prototipos no es una muy buena solución, pero tal vez esta sea la más rápida: defina este bloque de código;
que compruebe sus objetos propiedad isDomElement:
Espero que esto ayude.
fuente
De acuerdo con mdn
Podemos implementar
isElement
por prototipo. Aquí está mi consejo:fuente
Creo que lo que tiene que hacer es hacer un control minucioso de algunas propiedades que siempre estarán en un elemento DOM, pero su combinación no más probable estar en otro objeto, de este modo:
fuente
En Firefox, puedes usar el
instanceof Node
. EsoNode
se define en DOM1 .Pero eso no es tan fácil en IE.
Solo puede asegurarse de que sea un elemento DOM utilizando la función DOM y capturar si hay alguna excepción. Sin embargo, puede tener efectos secundarios (por ejemplo, cambiar el estado interno del objeto / rendimiento / pérdida de memoria)
fuente
Tal vez esta es una alternativa? Probado en Opera 11, FireFox 6, Internet Explorer 8, Safari 5 y Google Chrome 16.
La función no se dejará engañar, por ejemplo, esto
fuente
Esto es lo que descubrí:
Para mejorar el rendimiento, creé una función de invocación automática que prueba las capacidades del navegador solo una vez y asigna la función adecuada en consecuencia.
La primera prueba debería funcionar en la mayoría de los navegadores modernos y ya se discutió aquí. Simplemente prueba si el elemento es una instancia de
HTMLElement
. Muy sencilloEl segundo es el más interesante. Esta es su funcionalidad principal:
Comprueba si el es una instancia de la construcción que pretende ser. Para hacer eso, necesitamos acceso al constructor de un elemento. Es por eso que estamos probando esto en la declaración if. IE7 por ejemplo falla esto, porque
(document.createElement("a")).constructor
estáundefined
en IE7.El problema con este enfoque es que
document.createElement
realmente no es la función más rápida y podría ralentizar fácilmente su aplicación si está probando muchos elementos con ella. Para resolver esto, decidí almacenar en caché los constructores. El objetoElementConstructors
tiene nodeNames como claves con sus constructores correspondientes como valores. Si un constructor ya está almacenado en caché, lo usa desde el caché; de lo contrario, crea el Elemento, almacena en caché a su constructor para acceso futuro y luego lo prueba.La tercera prueba es el retroceso desagradable. Comprueba si el es un
object
, tiene unanodeType
propiedad establecida en1
y una cadena comonodeName
. Por supuesto, esto no es muy confiable, sin embargo, la gran mayoría de los usuarios ni siquiera deberían retroceder hasta ahora.Este es el enfoque más confiable que se me ocurrió mientras mantengo el rendimiento lo más alto posible.
fuente
Prueba si
obj
hereda del nodo .Node es una interfaz básica de la que heredan HTMLElement y Text.
fuente
diferenciar un objeto js sin formato de un elemento HTMLE
utilizar:
// O
utilizar:
o={}; o.is("HTML") // false o=document.body; o.is("HTML") // true
fuente
aquí hay un truco usando jQuery
poniéndolo en una función:
fuente
elem.nodeType === 1
¿por qué no guardar la sobrecarga de la llamada y la dependencia de jQuery y hacer que su función isElement lo haga por sí misma?No para forzar esto o cualquier cosa, sino para los navegadores compatibles con ES5, ¿por qué no simplemente:
No funcionará en TextNodes y no está seguro sobre Shadow DOM o DocumentFragments etc, pero se trabajará en casi todos los elementos de etiquetas HTML.
fuente
Esto funcionará para casi cualquier navegador. (No hay distinción entre elementos y nodos aquí)
fuente
Un método absolutamente correcto, el objetivo de verificación es un código primario de elemento html real :
fuente
Cada DOMElement.constructor devuelve la función HTML ... Element () u [Object HTML ... Element] así que ...
fuente
Tengo una forma especial de hacer esto que aún no se ha mencionado en las respuestas.
Mi solución se basa en cuatro pruebas. Si el objeto pasa los cuatro, entonces es un elemento:
El objeto no es nulo.
El objeto tiene un método llamado "appendChild".
El método "appendChild" fue heredado de la clase Node , y no es solo un método impostor (una propiedad creada por el usuario con un nombre idéntico).
El objeto es de Nodo Tipo 1 (Elemento). Los objetos que heredan métodos de la clase Node son siempre nodos, pero no necesariamente elementos.
P: ¿Cómo verifico si una propiedad determinada se hereda y no es solo un impostor?
R: Una prueba simple para ver si un método fue realmente heredado de Node es verificar primero que la propiedad tenga un tipo de "objeto" o "función". Luego, convierta la propiedad en una cadena y verifique si el resultado contiene el texto "[Código nativo]". Si el resultado se parece a esto:
Entonces el método ha sido heredado del objeto Node. Ver https://davidwalsh.name/detect-native-function
Y finalmente, uniendo todas las pruebas, la solución es:
fuente
Esto verificará incluso si es un elemento DOM de jQuery o JavaScript
fuente
La única forma de garantizar que está comprobando un elemento HTMLE real, y no solo un objeto con las mismas propiedades que un elemento HTML, es determinar si hereda del nodo, ya que es imposible crear un nuevo nodo () en JavaScript. (a menos que se sobrescriba la función Node nativa, pero no tendrá suerte). Entonces:
fuente