最近在苦读《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. Ehcache缓存实例

    一:目录 EhCache 简介 Hello World 示例 Spring 整合 Dummy CacheManager 的配置和作用 二: 简介 1. 基本介绍 EhCache 是一个纯Java的进程 ...

  2. hdu1233 继续畅通工程 (最小生成树——并查集)

    还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  3. LeetCode:27. Remove Element(Easy)

    1. 原题链接 https://leetcode.com/problems/remove-element/description/ 2. 题目要求 给定一个整数数组 nums[ ] 和一个整数 val ...

  4. Memcached Hash算法

    本文来自网易云社区 作者:吕宗胜 Hash算法 1. Memcached Hash介绍 我们在前面的文章中已经介绍过了Memcached的内存管理方式,LRU的策略.由于Memcached的数据存储方 ...

  5. springmvc基础篇—处理图片静态资源文件

    当我们在web.xml中对DispatcherServlet的过滤设置为/ 的时候,表示对所有的路径进行拦截过滤,那么不可避免的就会产生一个问题,那就是像图片这种静态资源文件我明明引用路径有,但就是加 ...

  6. CDateTimeUI类源码分析

    CDateTimeUI是duilib里选择日期的控件,继承于CLabelUI控件,用于记录已经选择的日期,选择控件则是调用win32的日期选择控件. CDateTimeUI包含两个类,一个是CDate ...

  7. 【python模块】——logging

    python学习——logging模块

  8. C++学习009预处理器指令符号 # ## #@ 符号的使用

    # ## #@ 符号是预处理器指令符号. 当预处理器遇到#指令符号时,会将#之后的部分用双引号括起来 当预处理去遇到##指令符号时,直接将##前后部分连接起来 当预处理器遇到#@指令符号,将#@之后的 ...

  9. 对SE的认识

    对SE的认识 简述 “架构师”,也就是SE,总是给外人一种比较牛逼的感觉,其实踏实做开发的真的很少关注这个title. 抛开这个名词,这个角色的存在的确有一定的意义,因为项目中需要一个能“带领大家前进 ...

  10. Source Tree基础教程2

    1.分支 项目——分支——推送 新分支要重新拉取项目后才可以看见 项目——拉取 2合并分支代码 将其他分支代码合并到当前分支——提交