【问题标题】:Check if variable is a valid node element检查变量是否是有效的节点元素
【发布时间】:2011-04-16 09:59:57
【问题描述】:

如何更改 JS 元素以查看它是节点还是空变量?

【问题讨论】:

标签: javascript dom-node


【解决方案1】:

这取决于空变量的含义。

如果你的意思是它没有赋值,你可以检查undefined

alert( someVariable !== "undefined" );

或者如果你知道它有一个值,并且需要查看它是否是一个元素,你可以这样做:

alert( someVariable && someVariable.nodeType );  

或者如果您需要验证它是否是类型 1 元素,您可以这样做:

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

这消除了文本节点、属性节点、cmets 和a bunch of others

【讨论】:

  • nodeValue 可能是空白/空/空,不是吗? !!(document.createElement('p')).nodeValue
  • 只要不是其他具有nodeType 属性的对象。不过,机会很小。
【解决方案2】:

使用 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"

【讨论】:

  • meder 指出总有一个 nodeType 并且这是正确的。这是我检查的第一件事,值为 1。标准将 nodeType 1 定义为“Element 表示元素 Element、Text、Comment、ProcessingInstruction、CDATASection、EntityReference”。问题是针对“元素”而不是文本、评论等。所以我的 isElement() 函数是正确的方法吗?还是我错了?
【解决方案3】:

一个节点?一个 DOM 元素?它会有一个.nodeType 属性。

关于nodeValue 的另一个答案,nodeValue 可以为空,但一个节点总是有一个nodeType

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-30
    • 2012-08-12
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 2020-02-21
    • 1970-01-01
    相关资源
    最近更新 更多