一 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"))//获取classconsole.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/falseconsole.log(input.getAttribute("checked")) //checkedconsole.log(input.checked) //trueconsole.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添加到div1function fun1(){var div1 = document.getElementById("div1");var span1 = document.getElementById("span1");div1.appendChild(span1);}//把span添加到div2function 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元素添加到div3function 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);