Estoy tratando de obtener:
document.createElement('div')  //=> true
{tagName: 'foobar something'}  //=> falseEn mis propios scripts, solía usar esto ya que nunca lo necesitaba tagNamecomo 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);truepara[] instanceof HTMLElement.HTMLElementsiempre es unfunction, asítypeofque 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", porqueNodeyHTMLElementson 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
documentelemento (en todos los navegadores). si lo necesita, debe intentar:x instanceof Element || x instanceof HTMLDocumentTodas 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
truerespectivamente. 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;objectpropiedad 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
trueofalsefuente
undefined && window.spam("should bork")nunca evalúa laspamfunció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
isElementpor 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. EsoNodese 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")).constructorestáundefineden IE7.El problema con este enfoque es que
document.createElementrealmente 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 objetoElementConstructorstiene 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 unanodeTypepropiedad establecida en1y 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
objhereda 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") // truefuente
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