摘要:展开的属性后发现,继承于一个对象,而这个对象又继承于对象。这证实了我们对的猜想。是比较新的模型,相比更加完善,不光有元素,还有节点和。关于,和的关系,就是长得像,有个别相似的功能,但是是完全不一样的东西。
Array,NodeList, HTMLCollection这三个概念和它们之间的关系有很多做了几年前端的同学都搞不清楚,经常遇到但是又感觉很陌生,剪不断理还乱的感觉。今天咱们就来理清这三个东西。
对于Array大家差不多都能弄明白,但是HTMLCollectio、NodeList和Array的关系好像总是很暧昧,有一点像但是又不那么像,可能是我比较笨,但是真的被它们弄得很头疼啊,所以今天下决心必须弄懂它们。
咱们先不管那么多概念和定义,先来看看这三个东西到底长什么样。咱们先创建一个html文件,里面就放三个嵌套的div:
NodeListDocument div1div2div3
首先让我们来研究一下NodeList,在浏览器中打开这个html文件,打开控制台输入:
document.querySelectorAll("div")
我们发现返回的NodeList中包含这三个div。展开NodeList的__proto__属性后发现,NodeList继承于一个NodeList对象,而这个NodeList对象又继承于Object对象。
NodeList除了length属性外还有其他5个方法(method),分别是entries, forEach, item, keys, values,这五个方法都是干什么用的呢?用一遍就知道:
调用entries方法会返回一个iterator(迭代器),关于iterator/iterable可以参见MDN,简单点说就是返回了一个可以遍历的对象,而这个对象实现了iterable protocal,所以需要用for...of遍历,所以我们可以:
var divs = document.querySelectorAll("div"); for(var item of divs.entries()){ console.log(item); }
结果返回了三个包含三个div对象数组(为什么不是三个key-value pair?),如图:
forEach的用法和Array的forEach用法一样,都是用于遍历集合元素:
var divs = document.querySelectorAll("div"); divs.forEach(function (el, index, list) { console.log(el); });
item()用于从NodeList中获取单个节点元素:
var divs = document.querySelectorAll("div"); console.log(divs.item(0));
打印结果:
返回一个iterator用于遍历NodeList的key:
var divs = document.querySelectorAll("div"); for (var key of list.keys()) { console.log(key); }
打印结果:
和keys()类似,返回一个iterator用于遍历NodeList的value,即html元素:
var divs = document.querySelectorAll("div"); for (var value of divs.values()) { console.log(value); }
打印结果:
通过对NodeList的研究我们发现,NodeList和Array没有继承关系,但是都有length属性和forEach方法,而且拥有几个特有的方法,主要都是用来遍历和取值用的。
HTMLCollection认识了NodeList,我们再来认识一下HTMLCollection,同样我们先获取到一个HTMLCollection,在控制台中输入并执行:
document.getElementsByTagName("div")
打印结果:
可以看到得到的HTMLCollection继承于一个HTMLCollection对象,而HTMLCollection又直接继承于Object对象,所以它和NodeList是平级的。HTMLCollection和NodeList一样包含了查询得到的html元素,length属性和item方法,但没有NodeList的entries, forEach, keys, values这四个方法,但是又多了一个namedItem(根据id和name筛选元素)方法...
看到了NodeList和HTMLCollection这两个家伙的真容,我们很好奇这两个有很多相似又相互独立的家伙是怎么被发明出来的呢?什么情况下得到的是NodeList,什么情况是HTMLCollection呢?
MDN上是这么介绍HTMLCollection的:
Note: This interface is called HTMLCollection for historical reasons (before the modern DOM, collections implementing this interface could only have HTML elements as their items).
翻译一下就是:
之所以叫它HTMLCollection是因为某些历史原因,在新一代DOM出现之前,实现HTMLCollection这个接口的集合只包含HTML元素,所以命名为HTMLCollection。
我们知道DOM节点(node)不光包含HTML元素,还包含text node(字符节点)和comment(注释),既然HTMLCollection只包含HTML元素,那NodeList是不是会包含所有类型的DOM节点呢,我们来试验一下,先写一段html:
this is patent contentthis is child content
然后执行:
var parent = document.querySelector(".parent"); console.log(parent.childNodes);
打印结果:
我们看到childNodes返回的是第一个div下面的所有DOM节点,包含3个text node(其中两个是换行符),一个子div,一个comment。这证实了我们对NodeList的猜想。
我们再看一下HTMLCollection,执行:
var parent = document.querySelector(".parent"); console.log(parent.children);
打印结果:
只包含了子div,也验证了MDN上的说法。
至于parent即有childNodes属性,又有children属性呢?
因为parent即是一个Node对象(拥有childNodes属性),又因为它有子元素所以它又是一个ParentNode对象(拥有children属性)。
至此,我们对NodeList和HTMLCollection应该有一个比较全面的认识,总结一下就是HTMLCollection是比较早期的模型,只能包含HTML元素,早期就有的接口如document.getElementsByClassName, document.getElementsByTagName返回的就是HTMLCollection。NodeList是比较新的模型,相比HTMLCollection更加完善,不光有HTML元素,还有text节点和comment。比较新的接口如document.querySelectorAll返回的就是NodeList。
关于NodeList,HTMLCollection和Array的关系,就是长得像,有个别相似的功能,但是是完全不一样的东西。
当然关于HTMLCollection和NodeList的故事还没有讲完,因为它们有时候是live(活的?动态的?),有时候是not live(死的?静态的?),关于这个话题,之后的文章再详细分析。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/95980.html
摘要:展开的属性后发现,继承于一个对象,而这个对象又继承于对象。这证实了我们对的猜想。是比较新的模型,相比更加完善,不光有元素,还有节点和。关于,和的关系,就是长得像,有个别相似的功能,但是是完全不一样的东西。 Array,NodeList, HTMLCollection这三个概念和它们之间的关系有很多做了几年前端的同学都搞不清楚,经常遇到但是又感觉很陌生,剪不断理还乱的感觉。今天咱们就来理...
摘要:唯一要注意的是返回的虽然是,但是实际上是元素集合,并且是静态的其他接口返回的和都是的。与相同的是它也是一个动态的集合,与不同的是,中保存的是一组无序的属性节点的集合。及以下版本浏览器中,注释属于算作因此会出现在里。而且是元素的集合。 NodeList v.s. HTMLCollection 主要有两个方面不一样1.包含节点的类型2.使用方法 1.包含节点的类型不同(重要) (1)Nod...
摘要:唯一要注意的是返回的虽然是,但是实际上是元素集合,并且是静态的其他接口返回的和都是的。与相同的是它也是一个动态的集合,与不同的是,中保存的是一组无序的属性节点的集合。及以下版本浏览器中,注释属于算作因此会出现在里。而且是元素的集合。 NodeList v.s. HTMLCollection 主要有两个方面不一样1.包含节点的类型2.使用方法 1.包含节点的类型不同(重要) (1)Nod...
摘要:结构如下是的返回结果是的结果不要在意两个数量的区别,首先是快照,节点数量和类型的快照,就是对节点增删,感觉不到,但是对节点内部内容修改,是可以感觉到的,比如修改是绑定的,节点的增删是敏感的可写性问题直接对,进行赋值,是失败的元素是可读的,是 Dom 结构如下: 1.dsfs 2.dsfs 3.dsfs 5.dsf...
阅读 1596·2021-11-22 14:45
阅读 1016·2021-11-17 09:33
阅读 3299·2021-09-02 09:48
阅读 956·2019-08-30 15:54
阅读 2744·2019-08-30 15:53
阅读 2526·2019-08-30 12:54
阅读 2226·2019-08-29 12:37
阅读 2404·2019-08-26 13:58