简体   繁体   English

如何在JavaScript中检测HTMLCollection / NodeList?

[英]How to detect HTMLCollection/NodeList in JavaScript?

I'm not sure my current implementation is available all the time: 我不确定我目前的实施是否始终可用:

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;
}

A common situation is {length:1,item:function(){return [];}} 常见的情况是{length:1,item:function(){return [];}}
The value of result in chrome / safari / opera is '[object NodeList]'. chrome / safari / opera中的结果值是'[object NodeList]'。
In firefox and IE 9 , it is '[object HTMLCollection]'. 在firefox和IE 9中,它是'[object HTMLCollection]'。

Which is the standard value? 哪个是标准值?

The following should return true , if nodes is of type NodeList 如果节点类型为NodeList ,则以下内容应返回true

NodeList.prototype.isPrototypeOf(nodes)

@DavidSpector, for HTMLCollection you can similarly use : @DavidSpector,对于HTMLCollection,您可以类似地使用:

HTMLCollection.prototype.isPrototypeOf(collection)

I would structure the code differently: 我会以不同的方式构造代码:

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));
}

Notes: 笔记:

  • less return paths make easier-to-read code 较少的返回路径使代码更容易阅读
  • stick with one type of logic, if possible (ie use less negated checks) 如果可能的话,坚持使用一种逻辑(即使用较少的否定支票)
  • "item" is not mandatorily in a nodeList "item"不是强制在nodeList中
  • use hasOwnProperty() instead of in 使用hasOwnProperty()而不是in
  • use square brackets to index into the list 使用方括号来索引列表
  • I don't think a try/catch is really necessary, but that might be wrong - you decide 我不认为尝试/捕获是真的必要,但这可能是错的 - 你决定
  • check for nodeType instead of tagName , as text nodes or comments do not have a name 检查nodeType而不是tagName ,因为文本节点或注释没有名称
  • add more checks to the && chain if you see fit 如果您认为合适,请在&&链中添加更多检查

script : 脚本

Element.prototype.isNodeList = function() {return false;}
NodeList.prototype.isNodeList = HTMLCollection.prototype.isNodeList = function(){return true;}

use like this : 使用这样

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
  */
}

Here is how to test if an object is a NodeList in modern browsers: 以下是如何在现代浏览器中测试对象是否为NodeList:

if (nodes instanceof NodeList) {
  // It's a NodeList object
}

Check if variable is an HTMLcollection or a dom element 检查变量是HTMLcollection还是dom元素

  var foo = document.getElementById('mydiv');
  var foo2 = document.getElementsByClassName('divCollection');
  console.log(foo instanceof HTMLElement);
  console.log(foo instanceof HTMLCollection);

This answer is probably really really late, but.... 这个答案可能真的很晚,但....

if (nodes == '[object NodeList]') {
  // It's a nodeList
}

I created a benchmark of all answers here to see, what is the best approve in speed. 我在这里创建了所有答案的基准,看看速度最佳的批准是什么。 Turns out NodeList.prototype.isPrototypeOf(nodes) is by far the fastest. 结果是NodeList.prototype.isPrototypeOf(nodes)是迄今为止最快的。 But in a normal use-case nodes instanceof NodeList would be fine too. 但在正常的用例nodes instanceof NodeList也可以。

I personally would just not pick the isNodeList function, because its slow, custom and too much overhead. 我个人不会选择isNodeList函数,因为它的速度慢,自定义和开销太大。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM