如何在JavaScript中检测HTMLCollection/NodeList?

sim*_* xu 22 javascript

我不确定我目前的实施是否始终可用:

function isNodeList(nodes) {
    var result = Object.prototype.toString.call(nodes);
    // modern browser such as IE9 / firefox / chrome etc.
    if (result === '[object HTMLCollection]' || result === '[object NodeList]') {
        return true;
    }
    //ie 6/7/8
    if (typeof(nodes) != 'object') {
        return false;
    }
    // detect length and item 
    if (!('length' in nodes) || !('item' in nodes)) {
        return false;
    }
    // use the trick NodeList(index),all browsers support
    try {
        if (nodes(0) === null || (nodes(0) && nodes(0).tagName)) return true;
    }
    catch (e) {
        return false;
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

常见的情况是{length:1,item:function(){return [];}}
chrome/safari/opera中的result值是'[object NodeList]'.
在firefox和IE 9中,它是'[object HTMLCollection]'.

哪个是标准值?

vin*_*hbc 35

如果节点类型为NodeList,则以下内容应返回true

NodeList.prototype.isPrototypeOf(nodes)
Run Code Online (Sandbox Code Playgroud)

@DavidSpector,对于HTMLCollection,您可以类似地使用:

HTMLCollection.prototype.isPrototypeOf(collection)
Run Code Online (Sandbox Code Playgroud)

  • ES lint 安全版本:`Object.prototype.isPrototypeOf.call(NodeList.prototype,nodes)` (3认同)

Tom*_*lak 22

我会以不同的方式构造代码:

function isNodeList(nodes) {
    var stringRepr = Object.prototype.toString.call(nodes);

    return typeof nodes === 'object' &&
        /^\[object (HTMLCollection|NodeList|Object)\]$/.test(stringRepr) &&
        (typeof nodes.length === 'number') &&
        (nodes.length === 0 || (typeof nodes[0] === "object" && nodes[0].nodeType > 0));
}
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 较少的返回路径使代码更容易阅读
  • 如果可能的话,坚持使用一种逻辑(即使用较少的否定支票)
  • "item" 在nodeList中不是强制性的
  • 用hasOwnProperty()而不是in
  • 使用方括号来索引列表
  • 我不认为尝试/捕获是真的必要,但这可能是错的 - 你决定
  • 检查nodeType而不是tagName,因为文本节点或注释没有名称
  • &&如果您认为合适,请在链中添加更多支票

  • `nodes.hasOwnProperty('length')` 在 Chrome 中为我返回 false。也许`typeof nodes.length === 'number'` 更好? (2认同)

Guj*_*501 13

脚本:

Element.prototype.isNodeList = function() {return false;}
NodeList.prototype.isNodeList = HTMLCollection.prototype.isNodeList = function(){return true;}
Run Code Online (Sandbox Code Playgroud)

使用这样:

var d; // HTMLCollection|NodeList|Element
if(d.isNodeList()){
  /*
    it is HTMLCollection or NodeList
    write your code here
  */
}else{
  /*
    it is not HTMLCollection and NodeList
    write your code here
  */
}
Run Code Online (Sandbox Code Playgroud)


ros*_*.dk 9

以下是如何在现代浏览器中测试对象是否为NodeList:

if (nodes instanceof NodeList) {
  // It's a NodeList object
}
Run Code Online (Sandbox Code Playgroud)

  • @Frondor为什么会这样? (2认同)

koe*_*ech 7

检查变量是HTMLcollection还是dom元素

  var foo = document.getElementById('mydiv');
  var foo2 = document.getElementsByClassName('divCollection');
  console.log(foo instanceof HTMLElement);
  console.log(foo instanceof HTMLCollection);
Run Code Online (Sandbox Code Playgroud)


小智 5

这个答案可能真的很晚了,但是......

if (nodes == '[object NodeList]') {
  // It's a nodeList
}
Run Code Online (Sandbox Code Playgroud)

  • 但这在 IE8 中不起作用 =( 你得到“[object Object]” (4认同)