文章目录
一、DOM
DOM(Document Object Model文档对象模型): 专门操作网页内容的一套对象和函数的总称
DOM标准:国际标准,由W3C负责制定并维护,几乎所有浏览器100%兼容
5件事: 增删改查+事件绑定
二、DOM树
DOM树:一个网页的所有内容在浏览器内存中,以树形结构(树形结构是最直观的展现上下级包含关系的结构。而网页内容中的元素结构,也是上下级包含关系)保存
-
浏览器读取到一个网页的内容,都会先在内存中创建一个唯一的树根节点对象: document
-
浏览器扫描网页内容,每扫描到 一项内容(元素、文本、属性…),就会自动 创建一个新的 节点对象(Node),保存当前这一项内容的属性和值。然后将新创建的节点对象,保存到DOM树上对应的位置。
三、查找元素
1. 不需要查找,就可直接获得元素/对象
- 根节点对象:
document
- html元素节点对象:
document.documentElement
- head元素节点对象:
document.head
- body元素节点对象:
document.body
2. 按节点间关系查找
按照元素在DOM树中的上下级或平级关系查找其它元素
适用: 已经获得一个DOM元素对象,想找这个DOM元素对象周围附近的元素时,才用节点间关系
a. 节点树(不建议使用)
包含所有网页内容的完整树结构,有2大类关系,6个属性:
i.父子关系: 4个属性
-
获得一个节点对象的父级节点对象
节点对象.parentNode
—— 返回一个节点对象 -
获得一个节点对象下的所有直接子节点对象的集合
节点对象.childNodes
—— 返回类数组对象 -
获得一个节点对象下的第一个直接子节点对象
节点对象.firstChild
—— 返回一个节点对象 -
获得一个节点对象下的最后一个直接子节点对象
节点对象.lastChild
—— 返回一个节点对象
ii. 兄弟关系: 2个属性
-
获得一个节点对象相邻的前一个兄弟节点对象
节点对象.previousSibling
-
获得一个节点对象相邻的下一个兄弟节点对象
节点对象.nextSibling
缺点: 节点树会将看不见的回车、空格等空字符也创建为节点对象。严重干扰我们的查找结果!
所以,今后几乎不用节点树。
b. 元素树
仅包含元素节点的树形结构
优点:不会受到看不见的空字符的干扰!
所以,将来只要按节点间关系查找元素时,都用元素树
i. 父子关系: 4个属性
-
获得一个元素对象的父级元素对象
元素对象.parentElement
—— 返回一个元素对象 -
获得一个元素对象下的所有直接子元素对象的集合
元素对象.children
—— 返回类数组对象 -
获得一个元素对象下的第一个直接子元素对象
元素对象.firstElementChild
—— 返回一个元素对象 -
获得一个元素对象下的最后一个直接子元素对象
元素对象.lastElementChild
—— 返回一个元素对象
ii. 兄弟关系: 2个属性
-
获得一个元素对象相邻的前一个兄弟元素对象
元素对象.previousElementSibling
-
获得一个元素对象相邻的下一个兄弟元素对象
元素对象.nextElementSibling
示例:
<!DOCTYPE HTML>
<html>
<head>
<title>DOM Tree</title>
<meta charset="utf-8" />
</head>
<body>
<span id="s1">Hello</span>
<h1>标题一</h1>
<script>
//获得body的第一个直接子元素span
var span=document.body.firstElementChild
console.log(span); //希望<span>…</span>
//获得span的下一个兄弟h1
var h1=span.nextElementSibling;
console.log(h1); //希望<h1>…</h1>
//获得body下所有直接子元素的集合:3个元素,返回一个类数组对象
console.log(document.body.children); //希望[span, h1, script]
</script>
</body>
</html>
3. 按HTML特征查找
1) 按id名查找一个元素
//在整个页面中通过id名查找元素
var 一个元素对象=document.getElementById("id名")
返回值:
- 如果找到符合要求的元素,则只返回一个元素对象
- 如果没找到,则返回null
注意:
.
前的主语必须是document
- 只找一个元素,所以函数名中
Element
没有s结尾,是单数形式。
示例:
<ul id="nav">
<li class="item">电影</li>
<li class="item">剧集</li>
</ul>
<script>
//查找id为nav的一个元素对象
var ulNav=document.getElementById("nav")
console.log(ulNav);
</script>
2) 按标签名查找多个元素
// 在指定父元素范围内通过标签名获取多个元素
var 类数组对象=任意父元素.getElementsByTagName("标签名")
返回值:
- 如果找到符合要求的元素,就返回类数组对象
- 如果没找到,返回空类数组对象: { length:0 }
注意:
- 找多个元素,所以返回值为类数组对象,函数名中的Elements以s结尾,表示复数
- 指定只在一个父元素范围内查找符合要求的元素。——优化,查找范围越小,查找越快!
- 不仅查找直接子元素,而且会在所有后代元素中查找符合要求的元素。
- 函数规定要返回类数组对象,那么在任何时候,都会返回类数组对象!
即使只找到一个元素,也会把这唯一的一个元素放在类数组对象中第一个位置返回。所以,如果只找到一个符合要求的元素时,必须用[0],取出类数组对象中第一个位置保存的元素对象,才能对这个元素对象继续执行后续操作!
示例:
<span>Hello World !</span>
<ul id="nav">
<li class="item">电影</li>
<li class="item">综艺
<ul>
<li class="item active">你好</li>
</ul>
</li>
<li class="item">剧集</li>
</ul>
<script>
//前提: 已经找到ulNav了
//想继续在ulNav下查找所有的li元素
var lis=ulNav.getElementsByTagName("li");
console.log(lis);
//查找整个页面中唯一的一个span元素,并设置span的字体颜色为红色
var span = document.getElementsByTagName("span")[0];
console.log(span);
span.style.color="red";//<span style="color:red">
</script>
3) 按class名查找多个元素
// 在指定父元素范围内通过class名获取多个元素
var 类数组对象=任意父元素.getElementsByClassName("class名")
返回值:
- 如果找到符合要求的元素,就返回类数组对象
- 如果没找到,返回空类数组对象: { length:0 }
注意:
- 找多个元素,所以返回值为类数组对象,函数名中的Elements以s结尾,表示复数
- 指定只在一个父元素范围内查找符合要求的元素。——优化,查找范围越小,查找越快!
- 不仅查找直接子元素,而且会在所有后代元素中查找符合要求的元素。
- 函数规定要返回类数组对象,那么在任何时候,都会返回类数组对象!
即使只找到一个元素,也会把这唯一的一个元素放在类数组对象中第一个位置返回。所以,如果只找到一个符合要求的元素时,必须用[0],取出类数组对象中第一个位置保存的元素对象,才能对这个元素对象继续执行后续操作!
示例:
<ul id="nav">
<li class="item">电影</li>
<li class="item">综艺
<ul>
<li class="item active">跑男</li>
<li class="item">爸爸</li>
<li class="item">极限</li>
</ul>
</li>
<li class="item">剧集</li>
</ul>
<script>
//想在ulNav下查找所有class为item的li元素
var lis=ulNav.getElementsByClassName("item");
console.log(lis);
//想class为active的一个元素字体变为绿色
var liActive=ulNav.getElementsByClassName("active")[0];
console.log(liActive);
liActive.style.color="green";
</script>
4)按name名查找多个表单元素:
//在整个页面范围内通过name名获取多个元素
var 类数组对象=document.getElementsByName("name名")
返回值:
- 如果找到符合要求的元素,就返回类数组对象
- 如果没找到,返回空类数组对象: { length:0 }
注意:
.
前的主语必须是document
组对象- 找多个元素,函数名中的Elements 以s结尾,表示复数
- 函数规定要返回类数组对象,那么在任何时候,都会返回类数组对象!
即使只找到一个元素,也会把这唯一的一个元素放在类数组对象中第一个位置返回。所以,如果只找到一个符合要求的元素时,必须用[0],取出类数组对象中第一个位置保存的元素对象,才能对这个元素对象继续执行后续操作! - 一般常用于表单组件
示例:
<form>
用户名:<input name="uname"><br/>
性别:<label><input type="radio" name="sex" value="1">男</label>
<label><input type="radio" name="sex" value="0">女</label>
</form>
<script>
//查找网页中两个name为sex的radio元素
var radios=document.getElementsByName("sex");
console.log(radios);
//查找网页中唯一一个name为uname的input元素,为其添加红色阴影
var input=document.getElementsByName("uname")[0];
console.log(input);
input.style.boxShadow="0 0 5px red";
</script>
4. 按选择器查找
**适用:**元素藏的深、分散,查找条件复杂
(1)只查找一个符合要求的元素
var 一个元素对象=任意父元素.querySelector("选择器")//返回一个元素对象
(2)查找多个符合要求的元素
var 类数组对象=任意父元素.querySelectorAll("选择器")//返回的一个元素集合
示例:
<div class="content">
<ul>
<li>首页</li>
<li>财经</li>
<li>娱乐</li>
</ul>
</div>
var l1 = document.querySelector(".content ul li"); //获得第一个li元素
var lis = document.querySelectorAll(".content ul li"); //获得所有li元素
四、DOM效果标准4步
(1). 查找所有可能触发事件的元素
(2). 绑定事件处理函数
(3). 查找要修改的元素
(4). 修改元素
4.1 事件绑定
事件: 浏览器自动触发的或用户手动触发的页面中内容或状态的变化
绑定事件处理函数: 2种
a. 手工在html中元素开始标签中绑定事件处理函数
<元素 on事件名="事件处理函数()">
<script>
function 事件处理函数(){ ... }
</script>
缺点:全手工添加,极其不便于维护!——几乎不用
b.在js中绑定
每个元素对象身上,都长着一批名称以on开头的"事件属性"
比如: onclick, onfocus, onmouseover,…
当一个元素身上发生了一个事件时,浏览器会先在这个元素身上找到对应的事件属性,并执行事件属性中保存的事件处理函数。
事件绑定: 提前在元素的某个事件属性上保存一个function函数。当事件发生时,浏览器就可以找到这个函数,并自动执行!
①先找到要触发事件的元素
②元素对象.on事件名=function(){ ... }
优点:自动绑定,可以与for循环配合批量绑定,集中绑定
<table id="data">
<tr>
<td>
<button>-</button>
<span>1</span>
<button>+</button>
</td>
</tr>
<tr>
<td>
<button>-</button>
<span>1</span>
<button>+</button>
</td>
</tr>
</table>
<script>
//1. 查找触发事件的元素:查找table下所有button元素
//1.1 先找id为data的table
var table=document.getElementById("data");
console.log(table);
//1.2 再在table范围内找所有button
var btns=table.getElementsByTagName("button");
console.log(btns);//类数组对象
//2. 绑定事件处理函数:
//先遍历查找结果中每个按钮对象
for(var btn of btns) {
//每遍历一个按钮对象,就为当前按钮绑定单击事件的处理函数
btn.onclick=function(){
alert("疼!")
}
}
</script>