一 JS 的 DOM
1 概述
DOM 是 Document Object Model 文档对象模型的缩写。根据 W3C 的 DOM 规范,它是一种与浏览器,平台,语言无关的接口,能够动态地修改 XML 和 HTML。
D:文档 – HTML文档 或 XML 文档
O:对象 – document 对象的属性和方法
M:模型
2 HTML DOM
DOM 是将 HTML 文档视为树结构, 定义访问和操作 HTML 文档的标准方法; DOM 树:节点(node)的层次。文档节点(document)、元素节点、属性节点、文本节点; DOM 把一个文档表示
为一棵家族树(父,子,兄弟)
3 获取元素
① document 变量
document 是 js 自定义的文档对象,当浏览器加载 HTML 网页时自动创建,自上而下每解析一行标签存入一行标签到 document 对象中。故获取元素对象时需注意执行到获取代码时,标签是否已经加载到 document 对象中。
② windown.onload 函数
j浏览器加载完 HTML 页面时会调用 onload 函数。可将代码放到该函数中,当浏览器加载完 HTML 再执行。
<script>
windown.onload = function(){
// 操作标签
}
</script>
③ 元素获取方式
通过元素 Id getElementById,返回拥有指定 id 的第一个元素,如果不存在则返回 null
通过标签名字 getElementsByTagName,返回一个包括所有给定标签名称的元素集合,如果没有
匹配的元素,返回一个空集。
通过 class 名字 getElementsByClassName,返回一个包含所有指定class名称的元素集合,可以
在任意元素上调用该方法。
只有元素被加载到 document 中才可以获取
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>获取元素</title>
</head>
<body>
<div id="div1" class="divClass">第一个盒子</div>
<div id="div2" class="divClass">第二个盒子</div>
<script>
// 获取元素对象,先要获取文档对象document(html加载时自动创建)
// 元素加载后就会存到document,文档加载完成执行函数
window.onload=function (){
//根据id获取元素:只能获取一个元素(id元素在html中必须唯一)
var box1= document.getElementById("div2");
// 这句话会最后执行
console.log(box1)
}
//根据id获取元素:只能获取一个元素
var box1= document.getElementById("div2");
// console.log(box1)
//根据元素的标签名称获取:可以获取页面的多个元素(获得一个集合)
var boxs= document.getElementsByTagName("div");
// 通过下标获取某个元素
// console.log(boxs[0])
//根据元素的class属性获取:可以获取页面的多个元素(class值可重复)
var divs= document.getElementsByClassName("divClass");
console.log(divs)
</script>
</body>
</html>
4 操作元素节点属性
标准属性操作
1.获取属性值:
元素对象[“属性名”]
元素对象.属性名
元素对象.getAttribute("属性名")
2.设置属性值:
元素对象[”属性名”] = 值
元素对象.属性名 = 值
元素对象.setAttribute("属性名", 值)
自定义属性操作
获取属性值: 元素对象.getAttribute("属性名")
设置属性值: 元素对象.setAttribute("属性名", 值)
例子
<!-- 元素 -->
<div id="div1" class="div" style="background-color: yellow;">div1</div>
<input type="checkbox" id="cb" checked="checked" />
<script>
//获取元素属性:div 的id属性值获取
// var div1= document.getElementById("div1");
var div1= document.getElementsByTagName("div")[0];//通过下标获取集合的元素对象
console.log(div1["id"])
console.log(div1.id)
console.log(div1.getAttribute("id"))
//获取class
console.log(div1.className)
//获取样式
console.log(div1.style.backgroundColor)
//设置元素的属性
div1.id="div2";
console.log(div1)
//设置自定义属性,只能使用setAttribute,来给属性设置值
// div1.email="aaa@123.com";
div1.setAttribute("eamil","huang@123.com")
console.log(div1)
console.log(div1.getAttribute("eamil"))
//布尔类型的属性获取
var input = document.getElementById("cb");
//属性名和属性值相同的属性,此时使用JS获取到的属性值是 true/false
console.log(input.getAttribute("checked")) //checked
console.log(input.checked) //true
console.log(input["checked"]) //true
</script>
5 Node 对象的属性和方法
① 常用属性
属性名 | 描述 |
---|---|
firstChild | 指向在子节点列表中的第一个节点 |
lastChild | 指向在子节点列表中的最后一个节点 |
childNodes | 所有子节点的列表 |
previousSibling | 指向前一个兄弟节点,如果这个节点就是第一个,那么该值为null |
nextSibling | 指向后一个兄弟节点,如果这个节点就是最后一个,那么该值为null |
parentNode | 父节点 |
② 常用方法
方法名 | 描述 |
---|---|
hasChildNodes() | 是否包含子节点 |
appendChild(node) | 将节点添加到子节点列表的末尾 |
removeChild(node) | 从子节点中删除node |
replaceChild(newNode,oldNode) | 替换子节点 |
insertBefore(newNode,refNode) | 在一个子节点前插入一个新的子节点,在refNode元素前插入newNode |
③ 灵活操作DOM
<body>
<span id="span1">span1</span>
<span id="span2">span2</span>
<span id="span3">span3</span>
<div id="div1" style="background-color: orange">1</div>
<div id="div2" style="background-color: hotpink">2</div>
<div id="div3" style="background-color: cadetblue;">3</div>
<button onclick="fun1()">把span1添加到div1</button>
<button onclick="fun2()">把span添加到div2</button>
<button onclick="fun3()">新建span元素添加到div3</button><br/>
<select id="character" size="7">
<option id="item1">大黄</option>
<option id="item2">小黄</option>
<option id="item3">小白</option>
<option id="item4">自由人</option>
</select>
<button onclick="fun4()">在小黄之前插入小小黄</button>
<button onclick="fun5()">把小黄换成小黑</button>
<button onclick="fun6()">删除小白</button><br/>
<script>
//把span1添加到div1
function fun1(){
var div1 = document.getElementById("div1");
var span1 = document.getElementById("span1");
div1.appendChild(span1);
}
//把span添加到div2
function fun2(){
var div2 = document.getElementById("div2");
var spans = document.getElementsByTagName("span");
//遍历集合对象
for(var i=0;i<spans.length;i++){
//js数组长度可变:我们考虑每次获取数组的第一个元素即可
div2.appendChild(spans[0])
}
}
//新建span元素添加到div3
function fun3(){
var div3 = document.getElementById("div3");
//新建元素
var span= document.createElement("span");
//元素设置内容
span.innerHTML="新建span元素";
div3.appendChild(span);
}
//在小黄之前插入小小黄
function fun4(){
//获取小黄
var item2 = document.getElementById("item2");
//创建小小黄
var option = document.createElement("option");
//把元素作为文本加入到另一个元素中,这种方式会覆盖之前的文本
option.innerHTML="小小黄";
//获取下拉框对象
var el = document.getElementById("character");
//在小黄之前插入小小黄
el.insertBefore(option,item2);
}
//把小黄换成小黑
function fun5(){
var el = document.getElementById("character");
var item2 = document.getElementById("item2");
var option = document.createElement("option");
option.innerHTML="小黑";
el.replaceChild(option,item2);
}
//删除小白
function fun6(){
var el = document.getElementById("character");
var item3 = document.getElementById("item3");
el.removeChild(item3);
}
</script>
</body>
二 事件处理
1 事件驱动编程
通过触碰按钮状态(产生事件),执行操作(调用函数)。当对象处于某种状态时,可以发出一个消息通知,然后对应的程序即可执行
2 事件驱动编程的核心对象
① 事件源
发出事件通知,发出消息;也就是事件主体(通常指元素和标签);
② 事件名称
发出什么样的通知的名称,比如鼠标到我头上了,我被别人点了一下;
③ 事件响应函数
此事件会调用那个函数,当这个事件发生时要执行什么样的操作;
④ 事件对象
当事件发生时,会产生一个描述该事件的具体对象,包括具体的参数等一起发给响应函数,响应函数可通过事件对象来了解事件的详细信息
<!--p元素是事件源;click是事件名称-->
<p style="color: red" id="p1" onclick="shout(event);">Hello world!</p>
<script>
//响应函数
function shout(e){//响应函数,监听函数
alert(e.clientX);//e事件对象
}
</script>
3 事件类型
① 鼠标事件
属性名 | 描述 |
---|---|
onclick | 当用户点击某个对象时调用的事件 |
ondblclick | 当用户双击某个对象时调用的事件 |
onmousedown | 鼠标按钮被按下 |
onmouseleave | 当鼠标指针移出元素时触发 |
onmousemove | 鼠标被移动 |
onmouseover | 鼠标移到某元素之上 |
onmouseout | 鼠标从某元素移开 |
onmouseup | 鼠标按键被松开 |
② 键盘事件
属性名 | 描述 |
---|---|
onkeydown | 某个键盘按键被按下 |
onkeypress | 某个键盘按键被按下并松开 |
onkeyup | 某个键盘按键被松开 |
③ 表单事件
属性名 | 描述 |
---|---|
onblur | 元素失去焦点时触发 |
onchange | 该事件在表单元素的内容改变时触发 |
onfocus | 元素获取焦点时触发 |
onsubmit | 表单提交时触发 |
<body>
<h3>用户表单</h3>
<form action="">
<p>账号:<input type="text" onblur="fnBlur()" onfocus="fnFocus()"></p>
<p>
日历:
<select>
<option value="">2020</option>
<option value="">2021</option>
<option value="">2022</option>
</select>
</p>
<p>
备忘录:
<textarea id="per" cols="30" rows="5"></textarea>
</p>
<p>
明信片:
<img id="headImg" src="img/1.jpg" width="200px" height="200px">
</p>
<p><input type="button" value="提交"></p>
</form>
<script>
//事件绑定:1 html元素上使用事件名称绑定
function fnBlur(){
console.log("触发失去焦点函数")
}
function fnFocus(){
console.log("触发获取焦点函数")
}
//事件绑定:2 元素对象.事件名绑定
var per = document.getElementById("per");
per.onchange=function (){
console.log("变了")
}
//事件绑定:对象.addEventListener() 事件方法绑定
var pic = document.getElementById("headImg");
//将事件以方法的方式绑定
pic.addEventListener("click",function (){
//点击切换图片
pic.src="img/2.jpg";
})
</script>
</body>
4 事件绑定方式
元素是不自带事件的, 为元素添加功能的时候, 需要先绑定上对应的事件(三种方式), 然后用户触发元素对应的事件时,执行之前绑定好的响应函数
① 在元素上使用onXxx属性绑定
// HTML,JS 交错在一起,维护性差
<input type="button" value="点" onclick="alert('OK');"/>
② 通过元素对象的事件属性绑定
<!--在该元素被加载完的时候没有绑定事件-->
<input type="button" value="点" id="btn"/>
//使用JS代码为元素绑定事件
//HTML 和 JS 完全分离开来,便于后期维护
//在input元素被加载后再根据id获取这个元素
//元素被加载后,再执行JS代码, 才能绑定成功
var btn = document.getElementById("btn");
btn.onclick = function(){
alert("OK");
}
// 或使用文档加载事件,在整个html文档加载完成之后再获取元素,绑定事件
window.onload = function(){
//这个函数中的代码会在整个文档加载完成之后再执行
//此时获取元素,可行
var btn = document.getElementById("btn");
btn.onclick = function(){
alert("OK");
}}
方式一和二不能为元素绑定多次相同的事件,通过为事件属性赋值的响应函数实现,后面的赋值会将前面的覆盖掉,若要为元素绑定多次相同的事件,可使用方式三
③ 通过元素对象的方法绑定事件
IE和非IE因浏览器兼容问题导致使用方法不同
IE
// IE 事件名称前必须加"on",多次添加监听后,触发顺序: 先添加的后执行
// EventName 事件名 fnHandler 事件响应函数
attachEvent [Object].attachEvent("EventName",fnHandler);
// fnHandler : 移除时,传入的"事件响应函数",必须和添加时传入的是同一个(通过相同标识符引用的那个函数) 匿名函数,每次创建的都不同
[Object].detachEvent("EventName",fnHandler);
//
非IE
// 非IE 直接使用事件(操作)名称,没有on,多次添加监听后,触发顺序: 先添加的先执行
addEventListener[Object].addEventListener("EventName",fnHandler);
// 移除时,传入的"事件响应函数",必须和添加时传入的是同一个(通过相同标识符引用的那个函数) 匿名函数,每次创建的都不同
[Object].removeEventListener("EventName",fnHandler);