23

How can I change a JS element to see if it is a node or an empty variable?

1

4 Answers 4

39

It depends on what you mean by an empty variable.

If you mean it hasn't had a value assigned, you can check for undefined

alert( someVariable !== "undefined" );

Or if you know it has a value, and need to see if it is an element, you could do something like this:

alert( someVariable && someVariable.nodeType );  

Or if you need to verify that it is a type 1 element, you could do this:

alert( someVariable && someVariable.nodeType === Node.ELEMENT_NODE );  

This eliminates text nodes, attribute nodes, comments, and a bunch of others.

Sign up to request clarification or add additional context in comments.

2 Comments

The nodeValue could be blank/empty/null, no? !!(document.createElement('p')).nodeValue
As long as it's not some other object with the property nodeType. Chances are slim, though.
10

A node? A DOM element? it would have a .nodeType property.

Regarding nodeValue for the other answer, the nodeValue can be empty but a node will always have a nodeType.

2 Comments

for HTMLElement nodes, nodeType === 1
Other objects may have nodeType property too. someVar instanceof Node or someVar instanceof Element will do the job
9

Using the HTML Element and taking a look at the Properties tab in Chrome Dev Tools we can see the descendants:

html->HTMLHtmlElement->HTMLElement->Element->Node->EventTarget->Object

Now we do not want to check the first 2 no matter what, too many different possibilities so that leave us with HTMLElement or Element. So what is the difference?

HTML, HEAD, SCRIPT, META, BODY, DIV, P and UL all have the same inheritance:

HTMLElement->Element->Node->EventTarget->Object

Now a few negative results from a typical document where:


<!DOCTYPE html>     DocumentType->Node->EventTarget->Object
<!-- COMMENT -->    Comment->CharacterData->Node->EventTarget->Object

So Node is the common denominator, but the question is to how to check for a Valid DOM Node it is how to check for a valid DOM Node Element. So any object with HTMLElement to return true, otherwise return false.

Ok now using the Chrome Dev Tools lets look at the HTML Element:

$obj.nodeType;      //1     No help what so ever
$obj.nodeName;      //HTML  Gives use the tag names
$obj.nodeValue;     //null  Waste of DOM space

let's check the prototype or __proto?

$obj.prototype.nodeType;    //TypeError
$obj.prototype.nodeName;    //TypeError
$obj.prototype.nodeValue;   //TypeError

$obj.__proto__.nodeType;    //undefined
$obj.__proto__.nodeName;    //undefined
$obj.__proto__.nodeValue;   //undefined

Ok so using node is dead to use. Lets move to the constructor.

$obj.constructor.name       
//"HTMLHtmlElement"     promising...

$obj.constructor.__proto__.prototype.toString()
//[object Object]

$obj.constructor.__proto__.constructor.name
Function

$obj.constructor.__proto__.prototype.constructor.name
HTMLElement
//BINGO

Now lets wrap in in a nice clean efficient utility function.

//readable version
isElement=function($obj){
    try {
        return ($obj.constructor.__proto__.prototype.constructor.name)?true:false;
    }catch(e){
        return false;
    }
}

/**
     * PRODUCTION
 * Return true if object parameter is a DOM Element and false otherwise.
 *
 * @param {object} Object to test
 * @return {boolean}
 */
isElement=function(a){try{return a.constructor.__proto__.prototype.constructor.name?!0:!1}catch(b){return!1}};

Tests:

$html=get('html')[0];           //[<html data-role=​"webpage" data-theme=​"dark" data-require=​"fa" data-hello=​"world">​…​</html>​]
isElement($html);               //"HTMLElement"
isElement($html.dataset);       //false
isElement($html.firstChild);    //"HTMLElement"
isElement($html.textContent);   //false

$tail=gei('tail');              //<tail id=​"tail">​…​</tail>​
isElement($tail);               //"HTMLElement"

isElement(get('title')[0]);     //"HTMLElement"

3 Comments

meder points out that there is always a nodeType and that is correct. That was the first thing I checked and the value is 1. The standard defined nodeType 1 as "Element Represents an element Element, Text, Comment, ProcessingInstruction, CDATASection, EntityReference". The question was for 'Element' not Text, Comment, etc. So my isElement() function is the correct way? or am I wrong?
your extensive research impressed me but your conclusion is not implemented in your isElement() function. it should check for $obj.constructor.__proto__.prototype.constructor.name === 'HTMLElement', as other node types' constructors have a name, too. thank you very much for your solution, and the challenge to check.
Your code is wrong: isElement(new XMLHttpRequest()) returns true, while XMLHttpRequest is not a valid DOM node. There is a simpler solution $obj instanceof Node
1

Test if javascript variable obj is valid DOM node element is very simple:

if (obj instanceof Node)
{
  //obj is DOM node element 
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.