2.03.10事件
1.事件的概念
- 介绍:事件是在编程时系统内发生的动作或者发生的事情,系统会在事件出现时产生或触发某种信号,并且会提供一个自动加载某种动作(列如:运行一段代码)的机制。例如:如果用户在网页上单击一个购买按钮,会显示一个购买确认信息框来响应这个动作。
- 概念:每个可用的事件都会有一个事件处理器,也就是事件触发时会运行的代码块。当我们定义了一个用来回应事件被激发的代码块的时候,我们说我们注册了一个事件处理器。注意事件处理器有时候被叫做事件监听器——从我们的用意来看这两个名字是相同的,监听器留意事件是否发生,然后处理器就是对事件发生做出的回应。
- 实操步骤
- 1.获取页面指定的标签
- 2.绑定事件
- 3.在事件函数作用域书写处理逻辑
<input type="button" value="按钮">
<script>
//1.获取页面指定标签
var btn=document.getElementsByTagName("input")[0];
var flag=true;
//2.绑定事件
btn.onclick=function(){
//3.书写处理逻辑
if(flag){
flag=false;
document.body.style.backgroundColor="pink";
}else{
flag=true;
document.body.style.backgroundColor="white";
}
}
</script>
- 注意:事件是一个标签的特殊属性,给标签绑定了事件,当你对这个标签作出事件的触发动作时,就调用给这个事件绑定的函数。当然,我们不一定作出事件的触发动作去调用给这个事件绑定的函数,我们可以直接调用事件的函数去运行函数。一句话说,就是标签对象的事件函数是标签对象的一个方法,这个方法可以通过一般的调用方法去调用(就是函数名加括号的方式),还可以通过触发某个动作而去调用。
2. 事件的绑定方式
- 介绍:JavaScript可以通过多种不同的方法将事件侦听器代码添加到网页,以便在关联的事件被触发时运行它。这种方法我们称之为事件的绑定方式
1.事件处理器属性
- 上面的例子中 onclick 是被用在这个情景下的事件处理器的属性,它就像 button 其他的属性(如 btn.textContent, btn.style), 但是有一个特别的地方 ———— 只要监听的事件触发你赋值给他的代码(事件处理函数)就会运行。
- 用法:
var btn = document.querySelector('button');
function bgChange() {
var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
document.body.style.backgroundColor = rndCol;
}
// 你可以将一个具名函数赋值给事件处理属性
btn.onclick = bgChange;
- 注意:如果需要取消事件处理器属性的事件处理函数,比如在某些App中当商品售完后购买按钮点击事件将会被取消。只需要将对应的事件处理器属性值赋值为null即可
var btn = document.querySelector('button');
function bgChange() {
var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
document.body.style.backgroundColor = rndCol;
console.log('我只可以点击一次')
// 取消按钮的点击事件处理函数
btn.onclick = null
}
// 你可以将一个具名函数赋值给事件处理属性
btn.onclick = bgChange;
2.行内事件处理器(不推荐使用)
- 介绍:在Web上注册事件处理程序的最早方法是类似于事件处理器属性的HTML属性(也称为内联事件处理程序)—属性值实际上是当事件发生时要运行的JavaScript代码。
- 用法:
<button onclick="alert('你好,这是我的旧式事件处理程序!');">Press me</button>
<button onclick="bgChange()">Press me</button>
<script>
function bgChange() {
var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
document.body.style.backgroundColor = rndCol;
}
</script>
- 注意:注意:通过上面的例子,你会发现HTML属性等价于许多事件处理器的属性;但是,你不应该使用这些 —— 他们被认为是不好的做法。使用一个行内事件处理属性似乎看起来很简单,但该用法会导致代码难以管理和效率低下。因为混用 HTML 和 JavaScript,使得文档很难解析,在开发中最好的行为是将 JavaScript 代码单独书写。并且该方法也不适用于给多个元素绑定相同事件处理方法
3.addEventListener() 和removeEventListener()
1.addEventListener()
- 介绍:DOM操作提供一种新的事件触发机制, 这个机制给浏览器提供了一个函数 addEventListener()。该函数和事件处理属性是类似的,但是语法略有不同。我们可以重写上面的随机颜色背景代码。例如:
var btn = document.querySelector('button');
function bgChange() {
var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
document.body.style.backgroundColor = rndCol;
}
// 你可以将一个具名函数赋值给事件处理属性
btn.addEventListener('click', bgChange)
- 概念:.addEventListener() 方法将指定的监听器注册到事件目标上,当该对象触发指定的事件时,指定的回调函数就会被执行。 事件目标可以是一个文档上的元素 Element,Document和Window或者任何其他支持事件的对象 (比如 XMLHttpRequest)。
- 语法:
target.addEventListener(type, listener);
target.addEventListener(type, listener, options);
target.addEventListener(type, listener, useCapture);
- 参数
- type:一个区分大小写的字符串,表示要侦听的事件类型。例 “click” 点击事件。
- listener:当指定类型的事件发生时,处理事件目标对象的回调函数。
- options :可选属性,一个指定有关 listener 属性的可选参数对象。可用的选项如下:
- capture: Boolean,表示事件是否使用捕获模式。(事件的捕获会在后面的课程中学习)
- once: Boolean,表示 listener 在添加之后最多只调用一次。如果是 true, listener 会在其被调用之后自动移除。
- passive: Boolean,该属性用来改善的滚屏性能,当值设置为true时,表示 listener 永远不会 阻止浏览器默认事件即永远不会调用 preventDefault()。如果 listener 仍然调用了这个函数,客户端将会忽略它并抛出一个控制台警告。(阻止浏览器默认事件会在后面的课程中学习)
- useCapture: Boolean,可选属性表示事件是否使用捕获模式。 默认为 false 。
- 注意:
- addEventListener 与 事件处理器属性不同的是,addEventListener可以给同一个事件监听器注册多个处理器
// 使用事件处理器属性无法给同一个事件同时绑定多个方法, functionB 会覆盖掉 functionA。我们也是通过这种方式取消事件的绑定
myElement.onclick = functionA;
myElement.onclick = functionB;
// 但是addEventListener可以给同一个事件同时绑定多个方法,这时functionA与functionB都会正常工作
myElement.addEventListener('click', functionA);
myElement.addEventListener('click', functionB);
- addEventListener 给同一个事件目标注册了多个相同的 EventListener,那么重复的实例会被抛弃。所以这么做不会使得 EventListener 被调用两次,也不需要手动清除多余的EventListener ,因为重复的都被自动抛弃了,但是前提是options中的capture的参数值一致,如果capture的值不一致,此时就算重复定义,也不会被抛弃掉。
function functionA() {
console.log('触发,我会给元素绑定同样的EventListener')
// functionA 被触发又一次给事件目标myElement注册了一个相同的EventListener,因为EventListener完全相同旧的事件监听将会被自动抛弃
myElement.addEventListener('click', functionA);
}
myElement.addEventListener('click', functionA);
function functionB() {
console.log('触发,我会给元素绑定同样的EventListener')
// functionA 被触发又一次给事件目标myElement注册了一个相同的EventListener,但是capture值与旧的EventListener不同,这时就的事件监听将不会被抛弃
myElement.addEventListener('click', functionB, true);
}
myElement.addEventListener('click', functionB);
2.removeEventListener()
-
概念:因为 addEventListener 可以给同一个事件监听器注册多个处理器,导致我们无法使用覆盖的方式删除已注册的监听事件,所以JavaScript提供了专门用来删除使用 .addEventListener() 方法添加的事件。使用事件类型,事件侦听器函数本身,以及可能影响匹配过程的各种可选择的选项的组合来标识要删除的事件侦听器。
-
语法:
target.removeEventListener(type, listener[, options]);
target.removeEventListener(type, listener[, useCapture]);
- 参数
- type:一个区分大小写的字符串,表示要侦听的事件类型。例 “click” 点击事件。
- listener:需要从目标事件移除的同一个处理事件目标对象的回调函数。
- options :可选属性,一个用来匹配需要删除指定事件侦听器特征的可选对象。
- capture: Boolean,表示事件是否使用捕获模式。(只有该属性影响匹配)
- useCapture: Boolean,可选属性表示事件是否使用捕获模式。 默认为 false 。
- 注意:删除指定的事件监听时,需要提供以前调用addEventListener()所提供的监听事件, 这样你或许可以达到移除此监听事件的目的. 并且, 你必须要提供相同的 type 、 listener 、 options 和 useCapture 参数给 removeEventListener()。注意 唯一需要 removeEventListener() 检测的是 capture/useCapture 标志. 这个标志必须与 removeEventListener() 的对应标志匹配, 但是其他的值不需要
element1.addEventListener("mousedown", handleMouseDown, true);
element1.removeEventListener("mousedown", handleMouseDown, false); // 失败
element1.removeEventListener("mousedown", handleMouseDown, true); // 成功
element2.addEventListener("click", handleMouseDown, { passive: true });
element2.removeEventListener("click", handleMouseDown, { passive: true }); // 成功
element2.removeEventListener("click", handleMouseDown, { capture: false }); // 成功
element2.removeEventListener("click", handleMouseDown, { capture: true }); // 失败
element2.removeEventListener("click", handleMouseDown, { passive: false }); // 成功
element2.removeEventListener("click", handleMouseDown, false); // 成功
element2.removeEventListener("click", handleMouseDown, true); // 失败
3. 事件分类
1.资源事件
- onload 页面元素(包括图像多媒体等)资源及其相关资源已完成加载。
- onbeforeunload用户退出页面
- 例如:
<script>
// 通过onload事件等待页面或图像加载完成后调用。
// 这样可以保证 HTML 文档加载完毕,在函数内部操作dom保证DOM 树是完整的
window.onload = function(){
// 获取页面上的元素
var row = document.getElementById('row');
var col = document.getElementById('col');
}
</script>
<body>
<input type="text" id="row">
<input type="text" id="col">
</body>
2.视图事件
- onresize 窗口或者框架被重新调整大小时触发
- onscroll 档视图或元素已被滚动。
- 例如:
<script>
// 监听窗口尺寸的变化
window.onresize = function(){
// 浏览器可视区尺寸变化了,执行当前函数
console.log("执行 onresize 事件函数");
}
// 监听页面滚动的事件(页面得产生滚动条)
window.onscroll = function(){
// 页面滚动变化了,执行当前函数
console.log("执行 onscroll 事件函数 页面滚动");
}
</script>
3.鼠标事件
-
onclick 单击 一次单击=一次按下鼠标+一次抬起鼠标
-
ondblclick 双击
-
onmousemove 在容器上移动鼠标
-
onmouseout 鼠标离开容器
- 这个行为会受到子元素的影响,父元素绑定了事件,从父元素身上移到子元素,也会再次触发该事件
-
onmousedown 按下鼠标
-
onmouseup 抬起鼠标
-
onmouseover 鼠标在容器上悬停
- 这个行为会受到子元素的影响,父元素绑定了事件,从父元素身上移到子元素,也会再次触发该事件,
-
onmouseenter 鼠标光标从元素外部移动到元素内部时触发,这个事件不冒泡
-
onmouseleave 位于元素内部的鼠标光标移动到元素范围之外触发,这个事件不冒泡
-
onmousewheel 鼠标的滚轮滚动
-
contextmenu 鼠标右键菜单展开时
4.键盘事件
- 注意:键盘事件的可绑定对象为:input标签,可编辑状态的标,document对象
- onkeydown 某个键盘按键被按下时触发.(不区分大小写)
- onkeyup 某个键盘按键被松开时触发
- onkeypress 除 Shift、Fn、CapsLock 外的任意键被按住。而且按住不放(长按),会连续触发。
5.表单事件
- onfocus 元素获得焦点(不会冒泡)。
- focus() 方法用于为 checkbox 赋予焦点。
- onblur 元素失去焦点(不会冒泡)。
- blur() 方法用于从链接上移开焦点。
- oninput 表单元素的输入事件当value发生变化时
- onchange 对于表单元素的值被用户提交时。与输入事件不同的是,对元素值的每次更改不一定会触发更该事件。
- reset 点击重置按钮时
- submit 点击提交按钮
6.区别onmouseleave与onmouseout
- onmouseleave在父容器中绑定事件,从子容器中离开也能触发事件,就是onmouseleave,使得容器及其子容器的范围之和划入事件监听的区域之中
- onmouseout在在父容器中绑定事件,从子容器中离开不能触发事件,就是onmouseenter,只使得容器本身区域划入事件监听的区域之中
- 例子:
<!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>
.box{
width: 200px;
height: 200px;
background-color: aqua;
position: relative;
}
.div{
position: absolute;
top: 200px;
width: 200px;
height: 200px;
background-color: red;
}
.box2{
margin-left: 250px;
width: 200px;
height: 200px;
background-color: rgb(146, 13, 224);
position: relative;
}
.div2{
position: absolute;
top: 200px;
width: 200px;
height: 200px;
background-color: rgb(240, 179, 25);
}
</style>
</head>
<body>
<div class="box">leave
<div class="div">leave</div>
</div>
<div class="box2">out
<div class="div2">out</div>
</div>
<script>
var box=document.querySelector(".box");
box.onmouseleave=function(){
console.log("我从box中leave的");
}
var div=document.querySelector(".box .div");
div.onmouseleave=function(e){
e.stopPropagation();
}
var box2=document.querySelector(".box2");
box2.onmouseout=function(){
console.log("我从box中out的");
}
var div2=document.querySelector(".box2 .div2");
div2.onmouseout=function(e){
e.stopPropagation();
}
</script>
</body>
</html>