01.DOM概述
Document Object Model
(DOM)文档对象模型:将标记语言文档的各个组成部分,封装为对象
,可以使用这些对象,对标记语言文档进行CRUD(增删改查)的动态操作。
通过 HTML DOM,可访问 HTML 文档的所有元素,当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model),HTML DOM 模型被构造为对象的树。
提示:Document 对象是 Window 对象的一部分,可通过 window.document 属性对其进行访问。
02.DOM事件概述
DOM事件:浏览器
和用户
可以对HTML页面做出某种动作,如浏览器加载页面后
,用户点击鼠标时
等,我们称这些动作为DOM事件。
事件是用户和页面交互的核心,当动作发生
(事件触发)时,我们可以为这个动作
(事件类型)绑定一个或多个处理事件的函数,通过这些绑定的函数来完成我们想要实现的功能。
举例如下:当我们点击
页面中的请点击我!
的时候,会触发一个弹窗事件,弹出hello!!!
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>demo</title>
</head>
<body>
<div id="root">请点击我!</div>
</body>
<!-- JS代码 -->
<script type="text/javascript">
// 通过DOM元素的id选择需要添加事件的DOM元素
var root= document.getElementById("root");
// 显示在控制台
console.log(root);
// 给该DOM元素添加一个事件,该事件的类型是onclick点击事件,事件对应的处理函数为弹窗
root.onclick = function (){
alert("hello!!!");
};
</script>
</html>
总结一下,事件的三要素:
- 事件源(是谁发生了事情):例子中的div标签
- 事件类型(发生了什么事):鼠标点击了该div标签
- 事件处理函数(怎么应对):弹出一个弹窗
03. 事件类型
当我们想HTML分配事件的时候,要先确定事件的类型
,如上面的例子
使用的事件类型就是点击事件
。
HTML中的事件类型有很多:鼠标事件
,框架/对象事件
,表单事件
,打印事件
,拖动事件
,多媒体事件
,动画事件
,过度事件
等。
- 鼠标事件:点击鼠标发生的事件
- 表单事件:处理表单使用的事件
具体参考:HTML DOM 事件
下面就演示几个比较简单的鼠标事件:
- 鼠标点击事件:
- 事件类型:onclick
- 功能:当用户
双击某个对象时
,调用的事件句柄(事件对应的函数)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>demo</title> </head> <body> <div id="root">请双击我!</div> </body> <script type="text/javascript"> var root= document.getElementById("root"); console.log(root); root.ondblclick = function (){ alert("hello!!!"); }; </script> </html>
- 鼠标移动事件:
- 事件类型:onmouseout
- 功能:当鼠标
从某个元素上移开时
,调用的事件句柄(事件对应的函数)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>demo</title> </head> <body> <div id="root">从我身上移开!</div> </body> <script type="text/javascript"> var root= document.getElementById("root"); console.log(root); root.onmouseout = function (){ alert("hello!!!"); }; </script> </html>
04.事件对象
每当有事件被触发,浏览器都会记录当前事件触发的详细信息,并把它们封装成一个对象,可以传递给事件处理函数,我们可以获取到该事件对象,事件对象也有自己的属性
和方法
。
- 事件属性:
- target:返回触发此事件的DOM元素
- type:返回当前事件对象的事件属性。
- 等等
- 事件方法:
- stopPropagation():不再派发事件
- 等等
事件绑定方式:
element.on+事件类型(type) = function (event){};
举个例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>demo</title>
</head>
<body>
<div id="root">事件对象相关的属性和方法验证请在控制台查看!!</div>
</body>
<script type="text/javascript">
var root= document.getElementById("root");
root.onmouseout = function (event){
var event=event || window.event; // 获取事件对象的兼容处理
console.log(event); // 打印事件对象本身
console.log(event.target); // 返回触发此事件的DOM元素
console.log(event.type); // 返回当前事件对象的事件属性。
};
</script>
</html>
05.事件的监听
监听绑定方式:
element.addEventListener(事件类型,function,boolean);
。- 同一事件类型可以绑定一个或多个事件处理程序,IE老版本不兼容。
- 也可以在第二个参数的位置直接使用
匿名函数
。
举个例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>demo</title>
</head>
<body>
<div id="root">点击事件!!</div>
</body>
<script type="text/javascript">
var root= document.getElementById("root");
// 点击事件
root.onclick = function (){
alert("hello!!")
};
//给点击事件添加事件监听:只要点击就触发
root.addEventListener("click",testListener,false);
function testListener(){
alert("监听点击事件:onclick")
};
</script>
</html>
监听解除方式:
element.removeEventListener(事件类型,function,false);
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>demo</title>
</head>
<body>
<div id="root">点击事件!!</div>
</body>
<script type="text/javascript">
var root= document.getElementById("root");
// 点击事件
root.onclick = function (){
alert("hello!!")
};
//给点击事件添加事件监听:只要点击就触发
root.addEventListener("click",testListener,false);
//给点击事件去除事件监听
root.removeEventListener("click",testListener,false);
function testListener(){
alert("监听点击事件:onclick")
};
</script>
</html>
另外:IE有个独有的方法obj.attchEvent(‘on’+type,function);
,功能和监听方式一样。
解除方式是:element.detachEvent(‘on’+type,function);
注意:如果绑定的是匿名函数
,则无法解除。
06.事件的捕获和冒泡
事件流:
- 当事件发生时,会在发生事件的元素节点与DOM树根节点之间按照特定的顺序进行传播, 这个过程称之为
事件流
。 - 即当页面触发一个事件时,会按照一定的顺序来响应事件,事件的响应过程称为事件流。
事件流分类:
- 冒泡型事件流
- 捕获型事件流
事件冒泡
:事件由子元素
传递到父元素
的过程叫做冒泡(false)。
- 事件
响应顺序
(向上响应
):文本节点–>元素节点—>body—>html—>document
捕获事件:事件由父元素传递到子元素的过程叫做事件捕获(ture)。
- 事件
响应顺序
(向下响应
):document–>html–>body–>元素节点–>文本节点
监听方式
根据提供的第三个参数设置事件捕获
或冒泡
:true则在捕获阶段
,false则在冒泡阶段(默认)
。
举个例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>demo</title>
</head>
<body>
<div id="father">
<div id="son">事件的捕获与冒泡</div>
</div>
</body>
<script type="text/javascript">
// 通过id方式获取父组件
var father=document.getElementById("father");
// 通过id方式获取子组件
var son=document.getElementById("son");
// 监听的时候绑定的第三个参数是false为冒泡方式,也是默认的方式。
// 点击后会先弹出:子组件
// 点击确认后再弹出:父组件
// 监听的时候绑定的第三个参数是true为捕获方式
// 点击后会先弹出:父组件
// 点击确认后再弹出:子组件
// 监听父组件的点击事件
father.addEventListener("click",fatherListener,false);
// 监听子组件的点击事件
son.addEventListener("click",sonListener,false);
// 监听之后执行的函数
function fatherListener(){
alert("父组件");
};
function sonListener(){
alert("子组件");
};
</script>
</html>
07.阻止事件冒泡的方式
方式一:事件委托
-
事件委托的功能:当子元素个数很多或不确定,且每个子元素都需要绑定执行
类似功能
的事件处理函数时,通过在父元素
上绑定该事件处理函数,在函数内部获取事件源对象
(某子元素),通过事件冒泡机制,确保能让每个子元素在被触发相应事件时,事件处理函数都能被正确执行。 -
事件对象有两个属性,
target
或srcElement(IE)
,它存储的是事件源对象
,即实际触发该事件的对象
,不是捕获的,也不是冒泡的,通过事件源对象,可以轻松实现事件委托功能。 -
举个例子:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>demo</title> </head> <body> <div id="root"> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> </ul> </div> </body> <script type="text/javascript"> // 一个数目很多的列表,我们要实现的功能是点击每个li都弹出它自己的内容 // 通过id方式获取根组件 var root=document.getElementById("root"); // 在根组件上绑定函数,根据冒泡机制,当点击子组件时,会以冒泡的形式向上层层触发 // 在子组件中不做处理,统一委派到根组件处理 root.onclick = function (event){ var event = event || window.event; // 获取产生事件的对象(子组件本身) target = event.target || event.srcElement; // 控制台查看 console.log(target); alert(target.innerText); }; </script> </html>
方式二:阻止事件冒泡
event.stopPropagation()
:可以阻止事件冒泡,阻止触发父级元素绑定的事件。- 举个例子:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>demo</title> </head> <body> <div id="father"> <div id="son">阻止事件冒泡</div> </div> </body> <script type="text/javascript"> // 通过id方式获取父组件 var father=document.getElementById("father"); // 通过id方式获取子组件 var son=document.getElementById("son"); // 监听父组件的点击事件 father.addEventListener("click",fatherListener,false); // 监听子组件的点击事件 son.addEventListener("click",sonListener,false); // 监听之后执行的函数 function fatherListener(){ alert("父组件"); }; function sonListener(event){ alert("子组件"); event.stopPropagation(); //阻止事件冒泡 }; </script> </html>