HTML DOM 允许 JavaScript 对 HTML 事件作出反应。JavaScript 能够在事件发生时执行,比如当用户点击某个 HTML 元素时。 JavaScript与HTML之间的交互是通过事件实现的。事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。
目录
事件是由三部分组成
执行事件的步骤
常用事件:
事件流
事件冒泡(IE事件流)
阻止事件冒泡 event.stopPropagation()
事件捕获(Netscape事件流)
DOM事件流
Dom0级事件和2级事件
阻止事件默认行为 preventDefault()
事件委托
事件类型
用户界面事件--UIEvent
焦点事件--FocusEvent
鼠标事件--MouseEvent
键盘事件--KeyboardEvent
页面跳转
对话框
事件是由三部分组成
事件源、事件类型、事件处理程序,我们也称为事件三要素。
1.事件源:事件被触发的对象 -->按钮对象
2.事件类型:如何触发?触发什么事件?例如鼠标点击,键盘按下等…
3.事件处理程序:通过一个函数赋值的方式
执行事件的步骤
1.获取事件源
2.注册事件(绑定事件)
3.采用函数赋值形式添加事件处理程序
常用事件:
-
当用户点击鼠标时
-
当网页加载后
-
当图像加载后
-
当鼠标移至元素上时
-
当输入字段被改变时
-
当 HTML 表单被提交时
-
当用户敲击按键时
-
....................
事件流
事件冒泡(IE事件流)
IE 事件流被称为事件冒泡,这是因为事件被定义为从最具体的元素(文档树中最深的节点)开始触发,然后向上传播至没有那么具体的元素(文档)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.outer{
width: 300px;
height: 300px;
background-color: red;
margin: 0 auto;
padding: 50px;
box-sizing: border-box;
}
.center{
width: 200px;
height: 200px;
background-color: pink;
padding: 50px;
box-sizing: border-box;
}
.inner{
width: 100px;
height: 100px;
background-image: linear-gradient(to right,red,pink,blue);
}
</style>
<script>
window.onload = function(){
var outer = document.querySelector('.outer');
var center = document.querySelector('.center');
var inner = document.querySelector('.inner');
outer.onclick = function(){
console.log('我是outer');
// alert('我是outer');
console.log(event.target,'触发事件的目标源');
console.log(event.currentTarget,'当前正在执行事件的dom元素');
}
center.onclick = function(){
console.log('我是center');
// alert('我是center');
// event.stopPropagation();
console.log(event.target,'触发事件的目标源');
console.log(event.currentTarget,'当前正在执行事件的dom元素');
}
inner.onclick = function(){
console.log('我是inner');
// alert('我是inner');
// 阻止事件冒泡 event表示当前的事件对象
// console.log(event,'事件对象');
// event.stopPropagation()
console.log(event.target,'触发事件的目标源');
console.log(event.currentTarget,'当前正在执行事件的dom元素');
}
}
</script>
</head>
<body>
<!-- 事件三要素 1.事件源 2.事件类型 3.事件处理程序 -->
<!-- 事件流 描述的是页面接受事件的顺序 事件冒泡:事件由内向外触发 事件捕获:事件由外向内触发 事件流机制:事件捕获 --到达目标 --事件冒泡 -->
<div class="outer">
<div class="center">
<div class="inner"></div>
</div>
</div>
</body>
</html>
在点击页面中的id为inner的div元素,click事件会以如下顺序发生
div#inner-----div#center-----div#outer-----body-----html-----document
也就是说,div#inner元素,即被点击的元素,最先触发 click 事件。然后,click 事件沿DOM 树一路向上,在经过的每个节点上依次触发,直至到达 document 对象。
阻止事件冒泡 event.stopPropagation()
事件捕获(Netscape事件流)
Netscape Communicator 团队提出了另一种名为事件捕获的事件流。事件捕获的意思是最不具体的节点应该最先收到事件,而最具体的节点应该最后收到事件。事件捕获实际上是为了在事件到达最终目标前拦截事件。如果前面的例子使用事件捕获,则点击div元素会以下列顺序触发 click 事件:document-----html ----- body ----- div
在事件捕获中,click 事件首先由 document 元素捕获,然后沿 DOM 树依次向下传播,直至到达实际的目标元素div。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.outer{
width: 300px;
height: 300px;
background-image: radial-gradient(red,pink,blue);
margin: 0 auto;
padding: 50px;
box-sizing: border-box;
}
.center{
width: 200px;
height: 200px;
background-color: red;
padding: 50px;
box-sizing: border-box;
}
.inner{
width: 100px;
height: 100px;
background-color: blue;
}
</style>
<script>
window.onload = function(){
var outer = document.querySelector('.outer');
var center = document.querySelector('.center');
var inner = document.querySelector('.inner');
function hander1(){
console.log('outer');
}
function hander2(){
console.log('center');
}
function hander3(){
console.log('inner');
}
/**
* false表示事件在冒泡阶段执行
* true 表示事件在捕获阶段执行
*/
outer.addEventListener('click',hander1,true);
center.addEventListener('click',hander2,true);
inner.addEventListener('click',hander3,true);
}
</script>
</head>
<body>
<div class="outer">
<div class="center">
<div class="inner"></div>
</div>
</div>
</body>
</html>
DOM事件流
DOM2 Events 规范规定事件流分为 3 个阶段:事件捕获、到达目标和事件冒泡。事件捕获最先发生,为提前拦截事件提供了可能。然后,实际的目标元素接收到事件。最后一个阶段是冒泡,最迟要在这个阶段响应事件。点击div元素会以如图所示的顺序触发事件。
在 DOM 事件流中,实际的目标(div元素)在捕获阶段不会接收到事件。这是因为捕获阶段从document 到html再到body就结束了。下一阶段,即会在div元素上触发事件的“到达目标”阶段,通常在事件处理时被认为是冒泡阶段的一部分。然后,冒泡阶段开始,事件反向传播至文档。大多数支持 DOM 事件流的浏览器实现了一个小小的拓展。虽然 DOM2 Events 规范明确捕获阶段不命中事件目标,但现代浏览器都会在捕获阶段在事件目标上触发事件。最终结果是在事件目标上有两个机会来处理事件。
Dom0级事件和2级事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function(){
var btn = document.querySelector('button');
// dom 0级事件绑定 on事件类型
btn.onclick = function(){
console.log(this);
}
// 追加事件
btn.onclick = function(){
console.log('第二次事件触发');
}
// 结果看出不可追加同一类型的事件
// dom 0级事件解绑
btn.onclick = null;
// dom 2级事件绑定 addEventListener() 参数: 事件类型 事件处理程序 true捕获/false默认冒泡
// btn.addEventListener('click',function(){
// console.log(this);
// })
// // 追加事件
// btn.addEventListener('click',function(){
// console.log('第二次事件触发');
// })
var handler1 = function(){
console.log(this);
}
var handler2 = function(){
console.log('第二次事件触发');
}
btn.addEventListener('click',handler1);
btn.addEventListener('click',handler2);
// 结果看出可以追加同一类型的事件
// dom 2级事件解绑 removeEventListener() 参数: 事件类型 事件处理程序
// btn.removeEventListener('click',handler1);
}
</script>
</head>
<body>
<button>点击这里</button>
</body>
</html>
dom0级事件
dom2级事件
dom0级和dom2级事件的区别
1.dom0级使用on关键字绑定和解绑事件,解绑将事件类型设置为null;
2.dom2级使用addEventListener()绑定事件,解绑使用removeEventListener();
3.dom0级事件不可追加同一类型事件 追加就是覆盖
4.dom2级事件可以追加同一类型事件 追加后依次执行
阻止事件默认行为 preventDefault()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function () {
var input = document.querySelector('input');
var a = document.querySelector('a');
// 阻止默认行为 preventDefault()
input.onclick = function () {
event.preventDefault();
}
a.onclick = function () {
event.preventDefault();
}
}
</script>
</head>
<body>
<form action="text.php">
<input type="submit" value="提交">
</form>
<a href="https://www.baidu.com">百度</a>
</body>
</html>
事件委托
在 JavaScript 中,页面中事件处理程序的数量与页面整体性能直接相关。原因有很多。首先,每个函数都是对象,都占用内存空间,对象越多,性能越差。其次,为指定事件处理程序所需访问 DOM 的次数会先期造成整个页面交互的延迟。只要在使用事件处理程序时多注意一些方法,就可以改善页面性能。
事件委托就是当事件触发时,把要做的事委托给父元素(或父元素的父元素)来处理。也就是:利用冒泡的原理,把事件加到父级上,通过判断事件来源的子集,执行相应的操作。使用事件委托技术能让你避免对特定的每个节点添加事件监听器。
事件委托利用事件冒泡,可以只使用一个事件处理程序来管理一种类型的事件。例如,click 事件冒泡到 document。这意味着可以为整个页面指定一个 onclick 事件处理程序,而不用为每个可点击元素分别指定事件处理程序。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function(){
var ul = document.querySelector('ul');
// 在这里加的li可以变色
// var newLi = document.createElement('li');
// newLi.innerText = '第11个li';
// ul.appendChild(newLi);
// var lis = document.querySelectorAll('li');
// for(var i=0;i<lis.length;i++){
// lis[i].onclick = function(){
// this.style.backgroundColor = 'red';
// }
// }
// 在这里加的li不可变色
var newLi = document.createElement('li');
newLi.innerText = '第11个li';
ul.appendChild(newLi);
// 事件委托,将子元素事件代理给父元素 绑定依次事件 管理一类事件
ul.onclick = function(){
// event 事件对象 event.target
event.target.style.backgroundColor = 'red';
}
}
</script>
</head>
<body>
<ul>
<li>第1个li</li>
<li>第2个li</li>
<li>第3个li</li>
<li>第4个li</li>
<li>第5个li</li>
<li>第6个li</li>
<li>第7个li</li>
<li>第8个li</li>
<li>第9个li</li>
<li>第10个li</li>
</ul>
</body>
</html>
事件委托(事件代理)
利用事件冒泡 只指定一个事件处理程序 就可以管理某一类事件
将子元素的事件绑定给父元素
目的:优化页面性能 减少事件的执行 减少浏览器的重排和回流 还可以给新增的元素绑定事件。
事件类型
用户界面事件--UIEvent
焦点事件--FocusEvent
鼠标事件--MouseEvent
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
width: 200px;
height: 200px;
border: 1px solid blue;
overflow: auto;
}
</style>
<script>
window.onload = function(){
var input = document.querySelector('input');
// select事件 在输入框中选择字符时触发
input.onselect = function(){
console.log('我被选择了');
console.log(window.getSelection().toString());
}
// resize事件 窗口缩放时触发方法
document.body.onresize = function(){
console.log(window.outerHeight,window.outerWidth);
}
// scroll事件 绑定滚动事件
var div = document.querySelector('div');
div.onscroll = function(){
console.log('正在滚动');
}
// 聚焦focus 失焦blur
input.onfocus = function(){
console.log('选中');
}
input.onblur = function(){
console.log('取消选中');
}
// 双击 dblclick
div.ondblclick = function(){
console.log('被双击');
}
// 鼠标移入mouseenter 移除mouseleave 一直移动mousemove
div.onmouseenter = function(){
console.log('鼠标移入');
}
div.onmouseleave = function(){
console.log('鼠标移出');
}
div.onmousemove = function(){
console.log('鼠标一直在移动');
}
}
</script>
</head>
<body>
<div>我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div
我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div
我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div我是一个div
</div>
<input type="text">
</body>
</html>
键盘事件--KeyboardEvent
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function(){
var input = document.querySelector('input');
// 键盘按下事件 keydown 按键keyCode
input.onkeydown = function(){
console.log(event.keyCode);
}
// 键盘抬起事件 keyup
input.onkeyup = function(){
console.log('抬起');
}
// 键盘持续按下事件 keyprogress
input.onkeypress = function(){
console.log('持续按下');
}
// 输入框输入事件 获取文本输入值
input.addEventListener('textInput',function(event){
console.log(event.data);
})
}
</script>
</head>
<body>
<input type="text">
</body>
</html>
页面跳转
open 打开页面 参数 url name 可配置对象 true自身打开 false 新窗口打开
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function(){
var btn1 = document.querySelectorAll('button')[0];
var btn2 = document.querySelectorAll('button')[1];
btn1.onclick = function(){
// open 打开页面 参数 url name 可配置对象 true自身打开 false 新窗口打开
w = window.open('https://www.baidu.com','_blank','height = 600px,width = 600px');
// 设置新窗口的宽高 resizeTo()
w.resizeTo(400,400);
// 设置新窗口的位置 moveTo()
w.moveTo(100,100);
}
btn2.onclick = function(){
// 关闭窗口
w.close();
}
}
</script>
</head>
<body>
<button>百度页面</button>
<button>关闭页面</button>
</body>
</html>
对话框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function(){
// 弹框 alert()
alert('弹框');
// 确认框 confirm()
var res = confirm('你确定么?')
if(res){
console.log('确定');
}else{
console.log('取消');
}
// 输入框 prompt()
var res = prompt('请输入你的姓名');
console.log(res);
}
</script>
</head>
<body>
</body>
</html>