JS的动态合集

前言

DOM是JavaScript重要组成部分,在DOM中有三个特别的集合分别是NodeList(节点的集合),NamedNodeMap(元素属性的集合)和HTMLCollection(html元素的集合)。这三个集合有一些共同的特点:它们都是一个类数组对象,可以通过中括号表达式来访问集合中元素,也有length属性。但它们并不是数组,而且它们都是动态的(querySelectorAll()返回的NodeList除外),会根据页面元素的变化而变化。下面就来介绍一下它们。

NodeList集合

如何获取NodeList集合

DOM将HTML页面解析成一个由多层次节点构成的结构。节点是页面结构的基础,而所有节点继承自Node类型,因此所有节点共享着基本的属性和方法。Node类型有一个childNodes属性,所以所有节点都拥有这个属性。而通过这个属性就可以得到一个保存着本节点的子节点组成的NodeList对象。

如何操作NodeList

NodeList可以通过方括号表达式来访问,也可以通过item()方法来访问,也有length属性,可以访问元素个数。 虽然javascript中的数组可以修改length属性。但NodeList集合并不是数组,而且它是页面一片区域的DOM结构映射。所以请不要修改NodeList对象的length值。

var firstChild = someNode.childNodes[0];//获取第一个元素
var secondChild = someNode.childNodes.item(1);//获取第二个元素
var count = someNode.childNodes.length;//获取集合长度

NamedNodeMap

如何获取NamedNodeMap

Element类型这种DOM节点是唯一拥有attributes属性的一种节点类型。而attribute属性中就包含NamedNodeMap集合。它由元素的特性组成。所以只要是元素节点,调用attributes属性就可以得到NamedNodeMap集合。

如何操作NamedNodeMap集合

可能一些人没有听过NamedNodeMap对象,该对象的常见实例对象是attributes属性

<div id="test"></div>
<script>
var attrs = test.attributes;
console.log(attrs instanceof NamedNodeMap); //true
</script>

NamedNodeMap集合的元素拥有nodeName和nodeValue属性,分别表示元素特性名称和特性值,也拥有以下方法:

  • getNamedItem(name);返回nodeName属性等于name的节点;
  • removeNamedItem(name);从列表中移除nodeName节点;
  • setNamedItem(node);向列表中添加节点,以节点nodeName为属性索引;
  • item(pos);返回位于数字pos位置的节点。
var className = element.attributes.getNamedItem('class').nodeValue;
var className1 = element.attributes['class'].nodeValue;
var oldAttr = element.attributes.removeNamedItem('class');

一般元素节点的getAttribute()、removeAttribute()和setAttribute()方法都可以完成以上操作

HTMLCollection

如何得到HTMLCollection集合

HTMLCollection是元素节点的集合可以通过getElementsByTagName()方法(获取同类型的元素)、getElementsByClassName()(获取class特性相同的元素)、getElementsByName()方法(获取name特性相同的元素)、document的anchors属性(包含name特性的a元素),forms属性(包含文档所有form元素),images属性(包含文档所有img元素),links属性(文档所有带href特性的a元素)。

与NodeList区别

NodeList集合主要是Node节点的集合,而HTMLCollection集合主要是Element元素节点的集合。Node节点共有12种,Element元素节点只是其中一种。

注意事项

这三个集合都是“动态的”;当文档结构发生变化时,它们都会更新,所以以下操作就会发生错误:

var divs = document.getElementsByTagName('div');
for (var i = 0; i
以上代码中的for循环将会一直执行,因为div得到的HTMLCollection集合是动态的,当每次给body添加元素divs都会进行更新,所以会一直循环下去。

解决方法1:将初始的集合的length存起来

var divs = document.getElementsByTagName('div');
for (var i = 0, var len = divs.length; i

解决方法2:将以上集合转化为数组

var divs = document.getElementsByTagName('div');
//将HTMLCollection转换为数组(此方法在IE8及以前不能用)
var divsArr = Array.prototype.slice.call(divs,0);
for (var i = 0; i
由于IE8-浏览器将NodeList实现为一个COM对象,不能使用Array.prototype.slice()方法,必须手动枚举所有成员 将以上集合转为数组的方法(通用):
function convertListToArray(nodes) {
var array = null;
try{//标准浏览器
array = Array.prototype.slice.call(nodes,0);
}catch(ex){//IE8及以下遍历每一项分别添加到数组中
array = new Array();
for(var i = 0,len = nodes.length;i

JS的静态合集

前言

除了getElementsByClassName()方法外,HTML5中DOM拓展了querySelectorAll()、querySelector()和matchesSelector()这3种方法,通过CSS选择符查询DOM文档取得元素的引用的功能变成了原生的API,解析和树查询操作在浏览器内部通过编译后的代码来完成,极大地改善了性能。 与getElementById()方法不同,querySelector()方法得到的对象是静态对象 与getElementsByTagName()等方法不同,querySelectorAll()方法得到的类数组对象是静态合集。

querySelector()

querySelector()方法接收一个CSS选择符,返回与该模式匹配的第一个元素,如果没有找到匹配的元素,返回null。该方法既可用于文档document类型,也可用于元素element类型。
<body style="height: 100%;">
<div class="box" id="box" style="height: 200px;">
<ul class="list" style="height:100px">
<li class="in" style="height: 30px;">1</li>
<li class="in" style="height: 30px;" title="test">2</li>
<li class="in" style="height: 30px;">3</li>
</ul>
</div>
<script>
//因为没有.null类名,所以返回null
var oNull = document.querySelector('.null');
console.log(oNull); //null
//通过<body>标签取得元素
var body = document.querySelector("body");
console.log(body.style.height); //100%
//通过id属性取得元素
var oBox = document.querySelector('#box');
console.log(oBox.style.height); //200px
//通过结合元素的类选择器取得元素
var oList = document.querySelector('ul.list');
console.log(oList.style.height); //100px
//通过类名取得元素
var oIn = document.querySelector('.in');
console.log(oIn.innerHTML); //1
//通过属性选择器取得元素
var oTest = body.querySelector('[title="test"]');
console.log(oTest.innerHTML); //2
</script>
</body>

querySelectorAll()

querySelectorAll()接收一个CSS选择符,返回一个类数组对象NodeList的实例。具体来说,返回的值实际上是带有所有属性和方法的NodeList,而其底层实现则类似于一组元素的快照,而非不断对文档进行搜索的动态查询。这样实现可以避免使用NodeList对象通常会引起的大多数性能问题。

没有匹配元素时,返回空的类数组对象,而不是null

<body style="height: 100%;">
<div class="box" id="box" style="height: 200px;">
<ul class="list" style="height:100px">
<li class="in" style="height: 30px;">1</li>
<li class="in" style="height: 30px;" title="test">2</li>
<li class="in" style="height: 30px;">3</li>
</ul>
</div>
<script>
//返回[]
var oNull = document.querySelectorAll('.null');
console.log(oNull);
//取得body元素
var body = document.querySelectorAll("body")[0];
console.log(body.style.height); //100%
//取得所有class为"in"的元素
var oIn = document.querySelectorAll('.in');
for (var i = 0; i < oIn.length; i++) {
console.log(oIn[i].innerHTML); //1,2,3
}
//取得title属性为test的元素
var oTest = body.querySelectorAll('[title="test"]');
console.log(oTest); //[li.in]
</script>
</body>

缺陷

selector类方法在元素上调用时,指定的选择器仍然在整个文档中进行匹配,然后过滤出结果集,以便它只包含指定元素的后代元素。它意味着选择器字符串能包含元素的祖先而不仅仅是所匹配的元素

<div id="container">
<div>1</div>
<div>2</div>
</div>
<script>
var container = document.getElementById('container');
console.log(container.querySelectorAll('div div')); //[div div]
</script>

所以,如果出现后代选择器,为了防止该问题,可以在参数中显式地添加当前元素的选择器

<div id="container">
<div>1</div>
<div>2</div>
</div>
<script>
var container = document.getElementById('container');
console.log(container.querySelectorAll('#container div div')); //[]
console.log(container.querySelectorAll('#container div')); //[div div]
console.log(container.querySelectorAll('div')); //[div div]
</script>

JS中的动态合集与静态合集的更多相关文章

  1. Vue.js 中的动态路由

    静态路由是不可以传递参数的.需要传递参数得用到动态路由 那么如何将参数作为路由呢? //在参数名前面加上 : ,然后将参数写在路由的 path 内 routes: [ //将页面组件与path指令的路 ...

  2. 浅谈js中如何动态添加表头/表列/表格内容

    我想很多童鞋用js动态向表格中添加数据很熟悉,而且也觉得非常简单!是的,对于写页面的童鞋来说,最喜欢写查询的页面了,动态向表格绑定数据.用for循环就可以轻松搞定. 如果我们的业务需求有所变化,可能我 ...

  3. QT中添加 动态库(.so) 和 静态库 (.a) 的方法

    在QT 的Makefile文件中: 1 添加动态库,如lipcap.so 则,在LIBS一行中添加“-L/usr/local/lib -lpcap”,依据自己的情况修改libpcap.so的路径 2 ...

  4. js中 ajax动态新增节点无法触发点击事件

    在写ajax加载数据的时候发现,后面添加进来的demo节点元素,失去了之前的点击事件. 其实最简单的方法就是直接在标签中写onclick="",但是这样写有些场景的是实现不了的,最 ...

  5. JS中的动态表格

    写法一:(有点啰嗦) //--------------XML DOM--------------------------------------function addTR(){ //1.取三个框的值 ...

  6. js中关于动态添加事件,不能使用循环变量的问题

    在编写事件的时候,我们难免会遇到以下这种情况:<!DOCTYPE html><html lang="en"><head> <meta ch ...

  7. JS 中html 动态替换

    一.定义通用替换js函数,或调用JQuery验证的$.format函数: //----通用JS操作// var a = "我喜欢吃{0},也喜欢吃{1},但是最喜欢的还是{0},偶尔再买点{ ...

  8. 深入理解Js中的this

    深入理解Js中的this JavaScript作用域为静态作用域static scope,但是在Js中的this却是一个例外,this的指向问题就类似于动态作用域,其并不关心函数和作用域是如何声明以及 ...

  9. JS动态引入js、CSS动态创建script/link/style标签

    一.动态创建link方式 我们可以使用link的方式.如下代码所示. function addCssByLink(url){ var doc=document; var link=doc.create ...

随机推荐

  1. zStack学习笔记(原创,绝对不是抄的……)

    我之前写的文章都没写上面那句,但是这篇写了,主要是因为zStack文章抄袭太严重……故此声明 因为涉及到数据的双向交互问题,所以在这里我考虑使用协议栈来实现数据的收发.首先说下如何在Zstack中添加 ...

  2. lodash toString 转换为字符串

    转换 value 为字符串. null 和 undefined 将返回空字符串.-0 将被转换为字符串"-0". _.toString(null); // => '' _.t ...

  3. linux c 获取网卡状态(UP or DOWN)

    源代码例如以下: #include <sys/socket.h> #include <sys/ioctl.h> #include <linux/if.h> #inc ...

  4. 窥探try ... catch与__try ... __except的区别

    VC中的这两个东西肯定谁都用过, 不过它们之间有什么区别, 正好有时间研究了一下, 如果有错误欢迎拍砖.基于VC2005, 32位XP 平台测试通过. 估计对于其他版本的VC和操作系统是不通用的. 1 ...

  5. Spring Sleuth和Zipkin跟踪微服务

    原文地址:http://www.cnblogs.com/skyblog/p/6213683.html 随着微服务数量不断增长,需要跟踪一个请求从一个微服务到下一个微服务的传播过程, Spring Cl ...

  6. spring揭秘读书笔记----spring的ioc容器之BeanFactory

    spring的ioc容器是一种特殊的Ioc Service Provider(ioc服务提供者),如果把普通的ioc容器认为是工厂模式(其实很相似),那spring的ioc容器只是让这个工厂的功能更强 ...

  7. YII2 学习

    下载地址: http://www.yiiframework.com/download/ http://www.yiichina.com/download 直接选择basic模板下载即可 下载之后解压到 ...

  8. unity, iOS下画面错乱解法

    unity版本号为5.1.1f1 Personal 在ipod5,系统为iOS7.1上测试.发现下面两种出现画面错乱的问题: 一,退后台在返回前台时画面发生错乱(错乱持续一两秒,然后变为正常).   ...

  9. 【从0開始Tornado建站】0.9版本号python站点代码开源--持续更新中

            从5月份開始[从0開始Tornado建站]这个专栏,開始一点一点把这个分类兴趣站点弄起来,从无到有的过程也是令人兴奋的:-) 国庆的时候等待备案然后上线,如今站点域名为ustchack ...

  10. discuz论坛模板文件目录

    公共模板文件夹 ./template/default/common/ common.css 公共CSS文件 faq.htm 帮助模板文件 footer.htm 系统总底部模板 footer_ajax. ...