Estou tentando obter:
document.createElement('div') //=> true
{tagName: 'foobar something'} //=> false
Nos meus próprios scripts, eu costumava usar isso, pois nunca precisava tagName
como uma propriedade:
if (!object.tagName) throw ...;
Portanto, para o segundo objeto, criei o seguinte como uma solução rápida - que geralmente funciona. ;)
O problema é que depende dos navegadores que aplicam as propriedades somente leitura, o que nem todos fazem.
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;
}
}
Existe um bom substituto?
javascript
dom
object
Jonathan Lonowski
fonte
fonte
Respostas:
Isso pode ser do seu interesse:
Faz parte do DOM, Nível2 .
Atualização 2 : Foi assim que eu o implementei na minha própria biblioteca: (o código anterior não funcionou no Chrome, porque Node e HTMLElement são funções em vez do objeto esperado. Este código é testado no FF3, IE7, Chrome 1 e Opera 9)
fonte
function Fake() {}; Fake.prototype=document.createElement("div"); alert(new Fake() instanceof HTMLElement);
true
para[] instanceof HTMLElement
.HTMLElement
é sempre umfunction
, por issotypeof
o expulsará da pista e executará a segunda parte da declaração. Você pode tentar, se desejarinstanceof Object
, porque a função será uma instância deObject
, ou apenas verificar explicitamentetypeof === "function"
, porqueNode
eHTMLElement
são ambas funções de objeto nativas.isElement(0)
, retorna 0, não falso ... Por que isso e como posso impedir isso?O código super-simples compatível com o IE8 a seguir funciona perfeitamente.
A resposta aceita não detecta todos os tipos de elementos HTML. Por exemplo, elementos SVG não são suportados. Por outro lado, esta resposta funciona tanto para HTML quanto para SVG.
Veja em ação aqui: https://jsfiddle.net/eLuhbu6r/
fonte
document
elemento (em todos os navegadores). se você precisar, você deve tentar:x instanceof Element || x instanceof HTMLDocument
Todas as soluções acima e abaixo (incluindo minha solução) sofrem da possibilidade de estar incorretas, especialmente no IE - é bem possível (re) definir alguns objetos / métodos / propriedades para imitar um nó DOM, tornando o teste inválido.
Geralmente, eu uso o teste de digitação no estilo pato: teste especificamente para as coisas que uso. Por exemplo, se eu quiser clonar um nó, testo-o assim:
Basicamente, é uma pequena verificação de sanidade + o teste direto de um método (ou propriedade) que estou planejando usar.
Aliás, o teste acima é um bom teste para nós DOM em todos os navegadores. Mas se você quer estar do lado seguro, verifique sempre a presença de métodos e propriedades e verifique seus tipos.
EDIT: O IE usa objetos ActiveX para representar nós, portanto, suas propriedades não se comportam como objetos JavaScript verdadeiros, por exemplo:
enquanto deve retornar "function" e
true
respectivamente. A única maneira de testar métodos é ver se eles estão definidos.fonte
Você pode tentar anexá-lo a um nó DOM real ...
fonte
obj.cloneNode(false)
. E não tem efeitos colaterais.Não há necessidade de hacks, basta perguntar se um elemento é uma instância do elemento DOM :
fonte
E os Lo-Dash's
_.isElement
?E no código:
fonte
Isso é da adorável biblioteca JavaScript MooTools :
fonte
Usando a detecção de raiz encontrada aqui , podemos determinar se, por exemplo, o alerta é um membro da raiz do objeto, que provavelmente será uma janela:
Para determinar se o objeto é a janela atual é ainda mais simples:
Isso parece ser mais barato que a solução try / catch no thread de abertura.
Don P
fonte
document.createElement()
mas também não inseridos no DOM. Incrível (: Obrigadothread antigo, mas aqui está uma possibilidade atualizada para os usuários ie8 e ff3.5 :
fonte
Sugiro uma maneira simples de testar se uma variável é um elemento DOM
ou como HTMLGuy sugeriu:
fonte
return typeof entity === 'object' && typeof entity.nodeType !== undefined;
object
e / ou propriedades, isso pode ser muito útil! Tx, @Roman// Na verdade, é mais provável que eu use esses inline, mas às vezes é bom ter esses atalhos para o código de instalação
fonte
Isso pode ser útil: isDOM
No código acima, usamos o operador de negação dupla para obter o valor booleano do objeto passado como argumento, dessa forma garantimos que cada expressão avaliada na instrução condicional seja booleana, aproveitando a Avaliação de Curto-Circuito , portanto a função retornos
true
oufalse
fonte
undefined && window.spam("should bork")
nunca avalia aspam
função falsa , por exemplo. Então não é!!
necessário, eu não acredito. Você pode fornecer um caso de borda [não acadêmico] em que seu uso é importante?!!
argumento "nunca é necessário" ( e, se não compra , estou curioso por que não ), você pode editar essa linhareturn !!(obj && typeof obj === "object" && obj.nodeType === 1 && obj.nodeName);
e fazê-la funcionar da mesma maneira.Você pode ver se o objeto ou nó em questão retorna um tipo de sequência.
fonte
typeof ({innerHTML: ""}).innerHTML === "string"
notANode.innerHTML = "<b>Whoops</b>";
, mais tarde, fazendo com que esse código passe seu objeto contaminado para esse código. Código defensivo === melhor código, todas as outras coisas iguais, e isso não é defensivo.Para aqueles que usam Angular:
https://docs.angularjs.org/api/ng/function/angular.isElement
fonte
function isElement(node) { return !!(node && (node.nodeName || (node.prop && node.attr && node.find))); }
parece um pouco com o @ finpingvin . Note-se que isso é a determinação " se uma referência é um elemento DOM (ou envolvido elemento jQuery). "Acho que a prototipagem não é uma solução muito boa, mas talvez seja a mais rápida: defina esse bloco de código;
do que verificar sua propriedade isDomElement dos objetos:
Eu espero que isso ajude.
fonte
De acordo com mdn
Nós podemos implementar
isElement
por protótipo. Aqui está o meu conselho:fonte
Eu acho que o que você tem a fazer é fazer uma verificação completa de algumas propriedades que estarão sempre em um elemento DOM, mas sua combinação não irá provavelmente estar em outro objeto, assim:
fonte
No Firefox, você pode usar o
instanceof Node
. IssoNode
é definido no DOM1 .Mas isso não é tão fácil no IE.
Você só pode garantir que seja o elemento DOM usando a função DOM e capturar se houver alguma exceção. No entanto, pode ter efeito colateral (por exemplo, alterar estado interno do objeto / desempenho / vazamento de memória)
fonte
Talvez isso seja uma alternativa? Testado no Opera 11, FireFox 6, Internet Explorer 8, Safari 5 e Google Chrome 16.
A função não será enganada, por exemplo, por
fonte
Isto é o que eu descobri:
Para melhorar o desempenho, criei uma função auto-invocadora que testa os recursos do navegador apenas uma vez e atribui a função apropriada de acordo.
O primeiro teste deve funcionar nos navegadores mais modernos e já foi discutido aqui. Apenas testa se o elemento é uma instância de
HTMLElement
. Muito simples.O segundo é o mais interessante. Esta é sua principal funcionalidade:
Ele testa se el é uma instância do construtor que finge ser. Para fazer isso, precisamos acessar o contratador de um elemento. É por isso que estamos testando isso na instrução if. O IE7, por exemplo, falha com isso, porque
(document.createElement("a")).constructor
estáundefined
no IE7.O problema com essa abordagem é que ela
document.createElement
realmente não é a função mais rápida e pode desacelerar facilmente seu aplicativo se você estiver testando vários elementos com ele. Para resolver isso, decidi armazenar em cache os construtores. O objetoElementConstructors
possui nodeNames como chaves e seus construtores correspondentes como valores. Se um construtor já estiver armazenado em cache, ele o usará do cache; caso contrário, ele criará o Elemento, armazenará em cache seu construtor para acesso futuro e, em seguida, testará contra ele.O terceiro teste é o fallback desagradável. Ele testa se el é um
object
, tem umanodeType
propriedade definida como1
e uma sequência comonodeName
. Isso não é muito confiável, é claro, mas a grande maioria dos usuários nem deveria voltar tão longe.Essa é a abordagem mais confiável que eu criei, mantendo o desempenho o mais alto possível.
fonte
Teste se
obj
herda do nó .O nó é uma interface básica da qual HTMLElement e Text herdam.
fonte
diferenciar um objeto js bruto de um HTMLElement
usar:
// OR
usar:
o={}; o.is("HTML") // false o=document.body; o.is("HTML") // true
fonte
aqui está um truque usando jQuery
colocando-o em uma função:
fonte
elem.nodeType === 1
isso internamente, por que não salvar a sobrecarga de chamada e a dependência do jQuery e sua função isElement faz isso sozinha?Para não se preocupar com isso ou qualquer outra coisa, mas para navegadores compatíveis com ES5, por que não apenas:
Não funcionará em TextNodes e não tem certeza sobre Sombra DOM ou DocumentFragments etc. mas irá funcionar em quase todos os elementos de tag HTML.
fonte
Isso funcionará para quase qualquer navegador. (Nenhuma distinção entre elementos e nós aqui)
fonte
Um método absolutamente certo, o destino da verificação é um código primário do elemento html real :
fonte
Cada DOMElement.constructor retorna a função HTML ... Element () ou [Object HTML ... Element] então ...
fonte
Eu tenho uma maneira especial de fazer isso que ainda não foi mencionada nas respostas.
Minha solução é baseada em quatro testes. Se o objeto passar pelos quatro, será um elemento:
O objeto não é nulo.
O objeto possui um método chamado "appendChild".
O método "appendChild" foi herdado da classe Node e não é apenas um método impostor (uma propriedade criada pelo usuário com um nome idêntico).
O objeto é do Nó Tipo 1 (Elemento). Os objetos que herdam métodos da classe Node são sempre nós, mas não necessariamente elementos.
P: Como verifico se uma determinada propriedade é herdada e não é apenas um impostor?
R: Um teste simples para verificar se um método foi realmente herdado do Node é primeiro verificar se a propriedade possui um tipo de "objeto" ou "função". Em seguida, converta a propriedade em uma sequência e verifique se o resultado contém o texto "[Código Nativo]". Se o resultado for algo parecido com isto:
Em seguida, o método foi herdado do objeto Node. Consulte https://davidwalsh.name/detect-native-function
E, finalmente, reunindo todos os testes, a solução é:
fonte
Isso verificará se é um elemento DOM jQuery ou JavaScript
fonte
A única maneira de garantir que você está verificando um HTMLEement real, e não apenas um objeto com as mesmas propriedades que um Elemento HTML, é determinar se ele é herdado do Node, pois é impossível criar um novo Node () no JavaScript. (a menos que a função Nó nativa seja substituída, mas você não terá sorte). Assim:
fonte