3.6、事件操作
3.6.1、注册事件方式
3.6.1.1、传统注册方法
利用on开头的事件,例如onclick
同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数
3.6.1.2、addEventListener
语法:
addEventListener(type,listener[,useCapture])
同一个元素同一个事件可以注册多个处理函数,按注册顺序依次执行
参数:
type:事件类型字符串,例如click、mouseover,注意这里不用带on
listener:事件处理函数,事件发生时,会调用该监听函数
useCapture:可选,是否在捕获阶段触发事件,需要一个布尔值,默认是false,在冒泡阶段处理程序,如果是true,就是在捕获阶段处理程序(后面事件流时,详细说)
注意:ie8及以下不支持
3.6.1.3、attachEvent
语法:
attachEvent(type,listener) 在ie8中可以使用,其他浏览器不能用
参数:
type:事件的字符串,要on
listener:回调函数
注意:
这个方法也可以同时为一个事件绑定多个处理函数,不同的是它后绑定先执行
3.6.2、解绑事件(删除事件)
3.6.2.1、传统注册方式解绑
eventTarget.οnclick=null
3.6.2.2、addEventListener方法注册解绑
eventTarget.removeEventListener(type,listener)
3.6.2.3、attachEvent 方法注册解绑
eventTarget.detachEvent(eventName,callback)
3.6.3、DOM事件流
3.6.3.1、事件流概述
事件流描述的是从页面中接收事件的顺序,事件发生时会在元素节点之间按照特定的顺序传播,这个传播的过程叫事件流
例如:给idiv绑定一个事件,时间流顺序如下
3.6.3.2、事件流3个阶段
(1)、捕获阶段:从触发事件的目标元素开始,事件被从目标元素的所有祖先元素依次往下传递(从外向内)
(2)、当前目标阶段:触发自己的事件
(3)、冒泡阶段:当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发(从内向外)
3.6.3.3、事件流指定阶段
js代码中只能执行捕获或者冒泡其中的一个阶段,其中onclick和attachEvent只能得到冒泡阶段,我们可以通过addEventListener(type,listener[,useCapture])中的第三个参数来分别演示冒泡和捕获
useCapture:可选,是否在捕获阶段触发事件,需要一个布尔值,默认是false,在冒泡阶段处理程序,如果是true,就是在捕获阶段处理程序
JavaScript复制代码
<body>
给box、box1绑定点击事件,弹出对应的信息
需求1:弹出box、box1信息
需求2:弹出box1、box信息
-->
<div class="box">
<div class="box1"></div>
</div>
<script>
var boxs = document.querySelectorAll("div");
// 需求1
// boxs[0].addEventListener(
// "click",
// function () {
// alert("我是box");
// },
// true
// );
// boxs[1].addEventListener(
// "click",
// function () {
// alert("我是box1");
// },
// true
// );
//需求2
boxs[0].addEventListener(
"click",
function () {
alert("我是box");
},
false
);
boxs[1].addEventListener(
"click",
function () {
alert("我是box1");
},
false
);
</script>
</body>
注意:
实际开发中我们很少使用事件捕获,我们更关注事件冒泡
有些事件是没有冒泡的,比如onblur、onfoucs、onmuseenter、onmouseleave
事件冒泡有时我们需要,有时需要避免
3.6.4、事件对象
3.6.4.1、概念
简单理解:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象,它有很多的属性和方法
JavaScript复制代码
1
box1.onmousemove = function (event) {};
3.6.4.2、注意:
●event 就是一个事件对象,写在我们侦听函数的小括号里面,当形参来看,这个形参,我们可以自己命名,例如event、evt、e等
●事件对象是当事件触发了,系统自动给我们创建的,不需要我们去传入实参
●事件对象在ie低版本中有兼容性问题,其兼容性的写法:event = event || window.event;,一般不用考虑
3.6.4.3、事件对象属性
e.target:返回触发事件的对象
e.type:返回事件的类型,比如:click、mouseover,不带on
e.cancelBubble:阻止冒泡 ie6-8使用(了解)
e.returnValue:阻止默认行为, ie6-8使用(了解)
e.preventDefault():阻止默认行为 非 ie6-8使用
e.stopPropagation():阻止冒泡 非 ie6-8使用
e.offsetX、e.offsetY:获取鼠标相对于当前元素的位置
e.clientX、e.clientY:获取鼠标相对于浏览器可见窗口的坐标
e.pageX、e.pageY:获取鼠标相对于文档页面的坐标
e.screenX,e.screenY:返回鼠标相对于电脑屏幕的x坐标
JavaScript复制代码
<body>
<div class="box">
<div class="box1"></div>
<a href="https://www.baidu.com/">百度</a>
</div>
<script>
var boxs = document.querySelectorAll("div");
var a = document.querySelector("a");
boxs[0].addEventListener("click", function (e) {
//e.target
console.log(e.target, "e");
console.log(this, "this");
//e.type
console.log(e.type, "e.type");
});
a.onclick = function (e) {
// 阻止默认行为
e.preventDefault();
// 阻止默认行为
// return false;
// 阻止冒泡
e.stopPropagation();
};
</script>
</body>
课堂小案例:
当鼠标在box1中移动时,在box2中来显示鼠标的坐标
JavaScript复制代码
<body>
<div id="box1"></div>
<div id="box2"></div>
<script type="text/javascript">
/* 需求:当鼠标在box1中移动时,在box2中来显示鼠标的坐标 */
//获取两个div
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
box1.onmousemove = function (event) {
// event = event || window.event;
var x = event.clientX;
var y = event.clientY;
//在box2中显示鼠标的坐标
box2.innerHTML = "x=" + x + "," + "y=" + y;
};
</script>
</body>
3.6.5、事件委托(代理、委派)
不给每个子节点单独设置事件监听,而是将事件统一绑定给元素的共同的祖先元素,然后利用冒泡原理影响设置每个子节点
通过事件委派可以减少事件绑定的次数,提高程序的性能
3.6.6、常用的键盘事件
键盘事件 | 触发条件 |
onkeyup | 某个键盘按键被松开时触发 |
onkeydown | 某个键盘按键被按下时触发 |
onkeypress | 某个键盘按键被按下时触发 |
e.keyCode 返回该键的ASCII值 键盘上每个字符有对应的数字