最近在苦读《JavaScript高级程序教程》,真不愧是前端圣经,学到了很多东西。

nodeList、NameNodeMap、HTMLCollection这三个集合是动态的!每当文档发生变化,它们都会得到更新。因此,它们始终保存着最新、最准确的信息。

在DOM这段遇到一个有意思的例子:

例子1: 增加内容

这个例子首先获取div,然后在一个for循环中,往body追加新的div元素。结果会一直追加。

第一个行代码会获取文档中所有<div>元素的HTMLCollection。这个集合是动态的。所以,只要有新的<div>元素被添加到页面中,这个元素也同时添加到

HTMLCollection中。而for循环每次都要对这个集合进行重新求值。所以就会出现这个有趣的例子。

<body>
<div></div>
<script>
// 获取div
let myDiv = document.getElementsByTagName('div');
for (let i = 0; i < myDiv.length; i++) {
console.log(myDiv);
let div = document.createElement('div');
document.body.appendChild(div);
// 为防止陷入死循环,这里设置一下
if (myDiv.length === 10) {
break;
}
}
</script>
</body>

改进1、

将length赋予一个变量。

<body>
<div></div>
<script>
// 获取div
let myDiv = document.getElementsByTagName('div');
// 改进
for (let i = 0,len = myDiv.length; i < len; i++) {
console.log(myDiv);
let div = document.createElement('div');
document.body.appendChild(div);
// 为防止陷入死循环,这里设置一下
if (myDiv.length === 10) {
break;
}
}
</script>
</body>

改进2、

使用 querySelectorAll('div') 代替 getElementByTagName('div')  

querySelectorAll()方法是DOM扩展里的方法,这个方法返回的是一个Nodelist实例,但是,返回的值实际上是带有所有属性和方法的NodeList,而底层实现类似于一组元素的快照,而非不断对文档进行搜索的动态查询,所以可以避免使用Nodelist对象通常引起的问题。

<body>
<div></div>
<script>
// 获取div
// 改进
let myDiv = document.querySelectorAll('div');
for (let i = ; i < myDiv.length; i++) {
console.log(myDiv);
let div = document.createElement('div');
document.body.appendChild(div);
// 为防止陷入死循环,这里设置一下
if (myDiv.length === ) {
break;
}
}
</script>
</body>

这两个返回结果都是一样的。

说完了增加,在看一下减少的问题

例二、

需求:现在我想把同时有 username 和 current 两个类名的标签,去掉其中的current类名。

按理说最后应该要输出三个div 每个div标签有一个类名 username

<body>
<div class="username current"></div>
<div class="username current"></div>
<div class="username current"></div>
<script>
// 获取
let userNames = document.getElementsByClassName('username current');
// 注意这里,把len赋予一个变量
for(let i = 0,len = userNames.length; i < len; i++){
userNames[i].classList.remove('current');
}
</script>
</body>

事实上是这样子的

以及这样子的

这是因为,把userNames的长度赋予一个变量导致的问题。len = 3;然后再for循环中,

第二次for循环的时候,i 的值为1,但是这时的userNames的数组长度是2。

因为第一次循环的时候已经把第一个div元素的current类去除了。

所以第二次循环时,remove的是最后一个div的类。

当第三次时,i为2, userNames的长度为1.。 所以这时取得的值为undefined,而undefined是基本数据类型,不能转为对象,理应没有方法。也就导致了语法错误。

改进1、

    <script>
// 获取
let userNames = document.getElementByClassName('username current');
// 改进
for(let i = 0;i < userNames.length; i++){
userNames[i].classList.remove('current');
}
</script>

改进2、

    <script>
// 获取
// 改进
let userNames = document.querySelectorAll('.username.current');
// 注意这里,把len赋予一个变量
for(let i = 0,len = userNames.length; i < len; i++){
userNames[i].classList.remove('current');
}
</script>

DOM操作的一个小坑的更多相关文章

  1. Go的List操作上的一个小“坑”

    转自http://sharecore.net/blog/2014/01/09/the-trap-in-golang-list/ 一直想不清楚一个问题,简单设计的东西到底是“坑多”还是“坑少”呢? 复杂 ...

  2. go的变量redeclare的问题,golang的一个小坑

    go的变量声明有几种方式: 1 通过关键字 var 进行声明 例如:var i int   然后进行赋值操作 i = 5 2 最简单的,通过符号 := 进行声明和赋值 例如: i:=5 golang会 ...

  3. 注意Android里TextView控件的一个小坑,用android:theme来设置样式时动态载入的layout会丢失该样式

    注意Android里TextView控件的一个小坑,用android:theme来设置样式时动态载入的layout会丢失该样式 这个坑,必须要注意呀, 比如在用ListView的时候,如果在List_ ...

  4. mysql url 连接配置的一个小坑。 工作中不会遇到。 学习的时候会

    <property name="driverClassName"> <value>com.mysql.jdbc.Driver</value> & ...

  5. 关于sniff函数的一个小坑

    最近在用scapy模块写一个关于WiFi的脚本时用到sniff函数,其中遇到了一个小坑,记录如下: sniff函数是在指定网卡上每次嗅探到一个数据包后然后将它传给prn指定的函数.

  6. Github作为图床的一个小坑

    Github作为图床的一个小坑 前言 听了少铭同学建议把github作为图床,结果遇到了一个小坑,总是显示不出来图片. 问题描述与解决 形如下的链接是显示不出来的: https://github.co ...

  7. [LeetCode]29 两数相除和一个小坑点

    给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 示例 1: 输 ...

  8. 小程序踩过的一个小坑---解析二维码decodeURIComponent() url解码

    因为我们需要用户扫码进入小程序,每一个货柜都有一个对应的二维码,当然每个二维码里的信息也不一样.用户扫码进入小程序之后,二维码的信息会以参数q带进去,而我们只能在onLoad事件中拿到这个参数, 但是 ...

  9. 关于js中 toFixed()的一个小坑

    作为一名前端,大家都应该知道,toFixed()的作用,toFixed()经常用于前台与后台数据格式的转换,套用下w3c上面的定义: 定义和用法toFixed(n) 方法可把 Number 四舍五入为 ...

随机推荐

  1. springmvc 配置多视图(jsp,freemarker,HTML等)

    SpringMVC 的 Controller 可以返回各种各样的视图.比如 JSP, JSON, Velocity, FreeMarker, XML, PDF, Excel, 还有Html字符流 等等 ...

  2. 1 http协议

    1.四层模型 + 2.socket 3.http协议 4. HTTP请求 跟踪了新浪的首页,我们来总结一下HTTP请求的流程: 3.1.1 步骤1:浏览器首先向服务器发送HTTP请求,请求包括: 方法 ...

  3. HMM相关文章索引

    HMM相关文章索引 1条回复 HMM系列文章是52nlp上访问量较高的一批文章,这里做个索引,方便大家参考. HMM学习 HMM学习最佳范例一:介绍 HMM学习最佳范例二:生成模式 HMM学习最佳范例 ...

  4. iOS-读写plist文件

    读写plist文件 问题,我有一个plist文件,表示56个民族的,但是里面保存的字典,我想转换成一个数组 好的,那么就先遍历这个plist,然后将结果保存到一个数组中,这里出现的一个问题就是C语言字 ...

  5. eclipse返回快捷键

    1.图上第一个箭头(Ctrl + Q) 返回上一个编辑点(编辑,修改代码) 2.图上第二个箭头(Alt + Left) 返回上一个操作点(点击进入方法等操作) 3.图上第三个箭头(Alt + Righ ...

  6. Python网络编程(线程通信、GIL、服务器模型)

    什么是进程.进程的概念? 进程的概念主要有两点: 第一,进程是一个实体.每一个进程都有它自己的地址空间, 一般情况下,包括文本区域(text region).数据区域(data region)和堆栈( ...

  7. QR码与DM码的区别

    DM无法表现汉字等其他形式,而QR码能用数据压缩方式来表示汉字,仅用13bit即可表示一个汉字,比其他二维条码表示汉字的效率提高了20%.相较而言,DM码信息容量小,应用简单.而QR在汉字处理上更有优 ...

  8. 【集训试题】SiriusRen的卡牌 set

    题意概述: 给出N张卡牌,每张有三个属性a,b,c,同时给出所有属性可能的最大值A,B,C.对于一张卡牌,当这张卡牌至少有两个属性大于另外一张卡牌的对应两个属性的时候,认为这张卡牌更加优秀.现在问有多 ...

  9. DFS——hdu5682zxa and leaf

    一.题目回顾 题目链接:zxa and leaf Sample Input 2 3 2 1 2 1 3 2 4 3 9 6 2 1 2 1 3 1 4 2 5 2 6 3 6 5 9   Sample ...

  10. [译]如何比较同一分支上的不同commit的代码区别?

    原文来源:https://stackoverflow.com/questions/3338126/how-do-i-diff-the-same-file-between-two-different-c ...