一. 什么是DOM: Document Object Model
文档 对象 模型
1. 什么是: 专门操作网页内容的一套对象和函数的集合
2. 为什么: 因为ECMAScript标准中,虽然定义js语言的语法(怎么说对,怎么说错),但是没有定义任何对象和函数可以操作或访问网页的内容
3. 何时: 今后只要想访问和操作网页的内容,都必须用DOM提供的对象和函数才行
今后jQuery,Vue,NG,react底层其实都是DOM
只有学好DOM,才能理解今后函数库和框架的原理,才能和框架配合一起完成任务,才有资格使用框架!
4. DOM标准: 由W3C制定的,规定如何操作网页内容的对象和函数的统一标准
(1). 为什么指定标准: 1998之前虽然所有浏览器都提供了操作网页内容的DOM对象和函数,但是每种浏览器提供的对象名和函数使用方法都不相同!几乎没有任何兼容性可言!
(2). W3C看不下去了!作为第三方牵头制定了统一标准!
今后凡是用DOM标准操作网页内容,所有浏览器几乎100%兼容
5. DOM能做什么: 5件事: 增删改查+事件绑定!
二. DOM树:
1. 什么是: 内存中保存一个网页中所有内容的树形存储结构
2. 为什么: 树形结构是最直观的展现上下级包含关系的结构。而网页中的HTML元素,刚好也是上下级包含关系!比如: ul下可包含多个li,table可包含多个行分组,行分组下可包含多个行,行下又可继续包含多个格。
3. 何时: 今后每做一个页面功能,都要先理清这个功能所有涉及的元素的树形结构关系,才能迅速找到想要的元素并修改元素
4. 如何生成DOM树的:
(1). 浏览器每读取到一个.html网页文件,都会先创建一个document对象,作为整棵树的树根对象。
(2). 然后再扫描网页内容,每扫描一项内容,就会在document下对应位置创建一个对象,保存当前扫描到的网页内容
名词解释: |
三. 查找元素:
1. 不需要查找就可直接获得: 4种:
(1). <html>元素: document.documentElement
(2). <head>元素: document.head
(3). <body>元素: document.body
(4). <form>元素:
a. 浏览器会将网页中所有的<form>元素都集中存储在document.forms"集合"里
(其实document.forms也是一个类数组对象,以下简称"集合")
b. 获得document.forms中的某一个表单元素对象?
1). document.forms[i] //获得当前页面中所有<form>元素中第i个<form>元素
2). document.forms["id"] //获得当前页面中id为指定"id"的表单元素
f12->Elements中: 右键点击某个元素,选Edit as html,就可以临时编辑这个元素的内容。编辑结束,点当前元素外边的空白处,临时引用编辑的新内容。——做实验用 |
2. 按HTML特征查找: 4种:
(1). 按id名查找一个元素对象:
a. var 一个元素对象=document.getElementById("id名")
获得 元素 按 id
b. 意为: 在整个页面中查找id为指定"id名"的元素对象
c. 返回值:
1). 如果找到,就返回一个元素对象
2). 如果没找到,返回null
d. 强调: .前必须用document调用!不能换成其他父元素对象
(2). 按标签名查找多个元素:
a. var 类数组对象=任意父元素对象.getElementsByTagName("标签名")
获得 元素们 按 标签 名
b. 意为: 在当前指定的父元素内部,查找指定标签名的多个元素
c. 返回值:
1). 如果找到符合条件的元素,就返回一个类数组对象,其中包含找到的符合条件的元素
强调: 即使只找到一个符合条件的元素,也会放在集合中返回!
如果想获得这唯一的一个符合的元素对象,必须"集合[0]",取出集合中0位置的元素对象,才能继续后续的操作!
2). 如果没找到,返回空类数组对象: {}.length=0
d. 强调:
1). .前可以写任意父元素对象,表示仅在指定的父元素内查找!
好处: 缩小查找范围,加快查找速度!
2). 不仅查找直接子代元素,而是查找所有后代中符合条件的元素
(3). 按class名查找多个元素:
a. var 类数组对象=任意父元素.getElementsByClassName("class名")
获得 元素们 按 class 名
b. 意思: 在一个指定的父元素内,查找class为指定名称的多个元素
c. 返回值:
1). 如果找到,返回一个包含所有符合条件的元素的类数组对象
强调: 即使只找到一个符合条件的元素,也会放在集合中返回!
如果想获得这唯一的一个符合的元素对象,必须"集合[0]",取出集合中0位置的元素对象,才能继续后续的操作!
2). 如果没找到符合条件的元素,返回空的类数组对象
d. 强调:
1). .前可以写任意父元素对象,表示仅在指定的父元素内查找!
好处: 缩小查找范围,加快查找速度!
2). 不仅查找直接子代元素,而是查找所有后代中符合条件的元素
3). 一个元素可能由多个class名来修饰,但是只需要其中一个class名就可找到该元素!
(4). 按name属性查找:
a. 何时: 专门查找有name属性的表单元素(input、select、textarea)
b. var 类数组对象=document.getElementsByName("name名")
获得 元素们 按 name
c. 意为: 在整个页面中查找多个指定name属性名的元素
d. 返回值:
1). 如果找到,返回一个包含所有符合条件的元素的类数组对象
强调: 即使只找到一个符合条件的元素,也会放在集合中返回!
如果想获得这唯一的一个符合的元素对象,必须"集合[0]",取出集合中0位置的元素对象,才能继续后续的操作!
2). 如果没找到符合条件的元素,返回空的类数组对象
e. 强调:
1). .前只能用document调用!——信任!不能换成其他任意父对象
示例: 使用按id查找和按标签名查找
<body> <span>Hello World !</span> <ul id="nav"> <li class="item parent">电影</li> <li class="item parent">综艺 <ul> <li class="item child active">跑男</li> <li class="item child">爸爸</li> <li class="item child">极限</li> </ul> </li> <li class="item parent">剧集</li> </ul> <script>//先删除script的src属性 //1. 按id查找一个存在的元素: 查找id为nav的ul var ul=document.getElementById("nav"); console.log(ul); //2. 尝试查找一个不存在的id: 查找id为tab的元素 var tab=document.getElementById("tab"); console.log(tab);//null //3. 在body下找唯一的一个span元素 //错误: //var span=document.body.getElementsByTagName("span") //获得的不是span元素对象,而是一个类数组对象,在类数组对象0位置放着我们想要的一个span元素对象。 //正确: 所以,要想获得查找结果类数组对象中0位置保存的这一个span元素,就必须用[0],从类数组对象中0位置取出这个span元素对象,才能继续后续操作。 var span=document.body.getElementsByTagName("span")[0]; console.log(span); //4. 查找ul元素对象内的所有li元素对象 //因为本来要找的就是多个li,所以,就应该获得一个包含多个li的集合。所以,没必要加[0] var lis=ul.getElementsByTagName("li"); console.log(lis) //5. 查找ul元素内的span元素对象 var spans=ul.getElementsByTagName("span"); console.log(spans); //返回空类数组对象: { length:0} //6. 在ul内查找所有class为item的li元素 var items=ul.getElementsByClassName("item"); console.log(items); //7. 在ul内查找所有class为parent的一级li元素 var parents=ul.getElementsByClassName("parent") console.log(parents); //8. 在ul内查找所有class为child的二级li元素 var children=ul.getElementsByClassName("child") console.log(children); //9. 在ul内查找一个class为active的li元素 var active=ul.getElementsByClassName("active")[0]; console.log(active); //10. 在ul内查找一个class为father的li元素(不存在) var father=ul.getElementsByClassName("father"); console.log(father);//空类数组对象! </script> </body> |
3. 按节点间关系查找:
(1).旧节点树:
a. 早期的DOM树,包含所有节点内容,甚至包含看不见的换行,空白等字符!
b. 2大类关系:
1). 父子关系:
i. 元素.parentNode 访问当前元素的父元素
ii. 元素.childNodes 访问当前元素的所有直接子元素
iii. 元素.firstChild 获得当前元素的所有直接子元素中第一个直接子元素
iv. 元素.lastChild 获得当前元素的所有直接子元素中最后一个直接子元素
2). 兄弟关系:
i. 元素.nextSibling 元素的下一个兄弟
ii. 元素.previousSibling 元素的前一个兄弟
c. 缺点: 看不见的空字符会极大的干扰查找!
d. 所以,今后几乎没人用节点树这六个属性
(2). 新元素树:
a. 新版本DOM中,定义了一棵新树,仅包含元素节点对象,不是元素的,一点儿都不包含!
b. 优点: 不包含看不见的空字符,排除了对查找的干扰!
c. 2大类关系:
1). 父子关系:
i. 元素.parentElement 访问当前元素的父元素
父 元素
特例: 其实旧的parentNode照样可用!不会受到干扰!因为在DOM树中能当爹的节点,肯定是元素节点!不可能是看不见的空字符节点!
所以: 依然可用parentNode,来简化parentElement
ii. 元素.children 访问当前元素的所有直接子元素
iii. 元素.firstElementChild 获得当前元素的所有直接子元素中第一个直接子元素
iv. 元素.lastElementChild 获得当前元素的所有直接子元素中最后一个直接子元素
2). 兄弟关系:
i. 元素.nextElementSibling 元素的下一个兄弟元素
ii. 元素.previousElementSibling 元素的前一个兄弟元素
(3). 难道内存中真的有两棵树吗?
其实内存中只有一棵最完整的节点树。所谓的元素树,只不过是在节点树中添加了一些专门指向元素节点的新属性而已!
(4). 示例: 使用节点树和元素树获得页面中指定的元素
<body> <span id="s1">Hello</span> <h1>标题一</h1> <script> //不能用live Server运行!应该直接在硬盘上打开网页文件! //获得body元素 var body=document.body; console.log(body); //获得body下所有直接子元素 var children=body.children; console.log(children);//3 //获得body下第一个直接子元素 var span=body.firstElementChild; console.log(span); //获得body下最后一个直接子元素 var script=body.lastElementChild; console.log(script); //获得h1: //可以是span的下一个兄弟元素 var h1=span.nextElementSibling; console.log(h1); //也可以是script的前一个兄弟元素 var h1=script.previousElementSibling; console.log(h1); //也可以是body所有直接子元素中第二个孩子元素 var h1=children[1]; console.log(h1); </script> </body> |