最近在苦读《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. Hue 工具使用

    Hue 是一个 Web 接口的 Hadoop 分析数据工具,由 Cloudra 公司开源 官方网址 Github 地址 -> 安装方法 文档地址 一.Build 1.ubuntu安装所需环境(以 ...

  2. stm8编程tips(stvd)

    编译完成时显示程序占用的flash和ram大小 将附件压缩包中的mapinfo.exe解压到stvd的安装路径\stvd中 在工程上点右键选settings 右侧的选项卡选择Linker,将categ ...

  3. vue整合mui

    步骤1:下载https://github.com/dcloudio/mui   步骤2:将下载来的包中的dist文件夹 放到vue项目的assets中 步骤3:修改webpack配置 找到build下 ...

  4. 简单工具 & 杂技

    图片压缩: 腾讯智图(http://zhitu.isux.us/) 手机的所有尺寸大小规范: http://screensiz.es/phone 需求: 移动端宽高一致的盒子(因为移动端屏幕宽度不一样 ...

  5. Windows下nginx作为静态资源服务器使用

    一.Nginx下载与安装 1.nginx官方下载地址:http://nginx.org/ 2.下载完后将压缩包解压即可 3.nginx配置文件为根目录下conf\nginx.conf 二.Nginx常 ...

  6. 接口测试工具postman(一)下载安装说明

    Postman是Google开发的一款功能强大的网页调试与发送网页HTTP请求,并能运行测试用例的的Chrome插件. 主要功能包括: 1.模拟各种HTTP requests 从常用的 GET.POS ...

  7. TW实习日记:第15天

    今天又是修修补补的一天,不过最开心的是因为项目比较特殊,有自己的后端服务器,有一些接口相关的bug可以让我直接写Java代码,终于可以碰一碰Java了哈哈.有好几个bug都是之前的人粗心设置了多余或者 ...

  8. Python音频处理(一)音频基础知识-周振洋

    1.声音音频基础知识 (1)声音是由震动产生,表现为波的形式.波有频率,振幅等参数.对于声波而言:频率越大,音调越高,反之越低.振幅越大,声音越大,反之越小. (2)采样率,帧率:波是连续(无穷)的, ...

  9. MySQL训练营03

    [任务四] #任务时间# 请于4月6日22:00前完成,在[打卡表格]处打卡.逾期尚未打卡的会被清退. 4.1 MySQL 实战 #学习内容# 数据导入导出 将之前创建的任意一张MySQL表导出,且是 ...

  10. IDEA运行lambda表达式

    在idea写了一个lambda的测试例子,但是运行一直报错, public class LambdaTest { public static void main(String[] args) { ne ...