【发布时间】:2011-04-16 09:59:57
【问题描述】:
如何更改 JS 元素以查看它是节点还是空变量?
【问题讨论】:
标签: javascript dom-node
如何更改 JS 元素以查看它是节点还是空变量?
【问题讨论】:
标签: javascript dom-node
这取决于空变量的含义。
如果你的意思是它没有赋值,你可以检查undefined
alert( someVariable !== "undefined" );
或者如果你知道它有一个值,并且需要查看它是否是一个元素,你可以这样做:
alert( someVariable && someVariable.nodeType );
或者如果您需要验证它是否是类型 1 元素,您可以这样做:
alert( someVariable && someVariable.nodeType === Node.ELEMENT_NODE );
这消除了文本节点、属性节点、cmets 和a bunch of others。
【讨论】:
!!(document.createElement('p')).nodeValue
nodeType 属性的对象。不过,机会很小。
使用 HTML 元素并查看 Chrome 开发工具中的“属性”选项卡 我们可以看到后代:
html->HTMLHtmlElement->HTMLElement->Element->Node->EventTarget->Object
现在我们无论如何都不想检查前两个,太多不同的可能性 这样我们就可以使用 HTMLElement 或 Element。那么有什么区别呢?
HTML、HEAD、SCRIPT、META、BODY、DIV、P 和 UL 都具有相同的继承性:
HTMLElement->Element->Node->EventTarget->Object
现在来自典型文档的一些负面结果:
<!DOCTYPE html> DocumentType->Node->EventTarget->Object
<!-- COMMENT --> Comment->CharacterData->Node->EventTarget->Object
所以节点是共同点,但问题是如何检查有效的 DOM 节点,如何检查有效的 DOM 节点元素。所以任何带有 HTMLElement 的对象都返回 true,否则返回 false。
好的,现在使用 Chrome 开发工具让我们看看 HTML 元素:
$obj.nodeType; //1 No help what so ever
$obj.nodeName; //HTML Gives use the tag names
$obj.nodeValue; //null Waste of DOM space
让我们检查一下原型还是__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
好的,所以使用节点已经死了。让我们转到构造函数。
$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
现在让我们使用一个干净高效的实用函数。
//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}};
测试:
$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"
【讨论】:
一个节点?一个 DOM 元素?它会有一个.nodeType 属性。
关于nodeValue 的另一个答案,nodeValue 可以为空,但一个节点总是有一个nodeType。
【讨论】: