一、事件监听机制
- 概念:
某些组件被执行了某些操作后,触发某些代码的执行。 - 事件:
某些操作。如:单击,双击,键盘按下了,鼠标移动了 - 事件源:
组件。如:按钮文本输入框… - 监听器:
代码。 - 注册监听:
将事件,事件源,监听器结合在一起。当事件源上发生了某个事件,则触发执行某个监听器代码。
二、常见的事件
1. 点击事件:
onclick :单击事件
ondblclick :双击事件
2. 焦点事件
onblur:失去焦点
onfocus :元素获得焦点。
//焦点事件
//1.失去焦点事件,用于表单校验
document.getElementById("username").onblur = function(){
alert("失去焦点了");
}
3. 加载事件:
onload :一张页面或一幅图像完成加载。
//2.加载完成事件 onload 页面加载完成执行onload代码
window.onload = function(){
//失去焦点事件
document.getElementById("username").onblur = function(){
alert("失去焦点了");
}
}
4. 鼠标事件:
onmousedown 鼠标按钮被按下。定义方法时,定义一个形参,接受event对象;event对象的button属性可以获取鼠标哪个键被点击了;0左键;1中键;右键2;
//鼠标移到元素上的事件
document.getElementById("username").onmouseover = function(){
alert("鼠标来了");
}
//鼠标点击事件
document.getElementById("username").onmousedown = function(event){
// alert("鼠标点击了");
alert(event.button);
}
1.禁止鼠标右键菜单
contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单
document.addEventListener('contextmenu', function(e) {
e.preventDefault();
})
2.禁止鼠标选中(selectstart 开始选中)
document.addEventListener('selectstart', function(e) {
e.preventDefault();
})
鼠标事件对象
event对象代表事件的状态,跟事件相关的一系列信息的集合。现阶段我们主要是用鼠标事件对象 MouseEvent 和键盘事件对象 KeyboardEvent。
跟随鼠标移动案例
var pic = document.querySelector('img');
document.addEventListener('mousemove', function(e) {
var x = e.pageX;
var y = e.pageY;
pic.style.top = y - 40 + 'px';
pic.style.left = x - 50 + 'px';
})
5. 键盘事件:
document.getElementById("username").onmousedown = function(event){
//判断是否是回车按钮
if(event.keyCode == 13){
alert("提交表单");
}
}
注意:
- 如果使用addEventListener 不需要加 on
- onkeypress 和前面2个的区别是,它不识别功能键,比如左右箭头,shift 等。
- 三个事件的执行顺序是: keydown – keypress — keyup
键盘事件对象
注意: onkeydown 和 onkeyup 不区分字母大小写,onkeypress 区分字母大小写。
在我们实际开发中,我们更多的使用keydown和keyup, 它能识别所有的键(包括功能键)
Keypress 不识别功能键,但是keyCode属性能区分大小写,返回不同的ASCII值
6. 选择和改变
onchange 域的内容被改变。
onselect 文本被选中。
<select name="" id="city">
<option value="">---请选择---</option>
<option value="">北京</option>
<option value="">上海</option>
<option value="">成都</option>
</select>
<script>
document.getElementById("city").onchange = function(event){
alert("改变了");
}
</script>
7. 表单事件:
onsubmit 确认按钮被点击。可以阻止表单提交;方法返回false则表单被阻止;
onreset重 置按钮被点击。
- 阻止表单提交方式一:
<form action="#" id="form">
<input type="text" id="username">
<select name="" id="city">
<option value="">---请选择---</option>
<option value="">北京</option>
<option value="">上海</option>
<option value="">成都</option>
</select>
<input type="submit" value="提交">
</form>
script
document.getElementById("form").onsubmit = function(){
//校验用户名格式是否正确
var flag = false;
return flag;
}
阻止表单提交方式二:
<form action="#" id="form" onclick="return checkForm();">
<input type="text" id="username">
<select name="" id="city">
<option value="">---请选择---</option>
<option value="">北京</option>
<option value="">上海</option>
<option value="">成都</option>
</select>
<input type="submit" value="提交">
</form>
script
function checkForm(){
return false;
}
三、注册事件(绑定事件)
1、HTML事件处理程序(不推荐使用)
<a "hide()">
2、传统的DOM事件处理程序
即在目标DOM事件的基础上绑定事件。如果在声明函数时加上括号,函数会立即调用,去掉括号,函数不会立即调用。
function change(){
//code
}
var name = document.getElementById("name");
name.onclick = change; //
3、addEventListener 事件监听方式
element.addEventListener(event, function, useCapture);
eventTarget.addEventListener()方法将指定的监听器注册到 eventTarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数。
该方法接收三个参数:
- type:事件类型字符串,比如 click 、mouseover ,注意这里不要带 on。指定事件名称。
- listener:事件处理函数,事件发生时,会调用该监听函数。
- useCapture:可选参数,是一个布尔值,为true时为捕获传递,当参数为false时为冒泡传递。默认值为false。
<p>实例演示了在使用 addEventListener() 方法时如何传递参数。</p>
<p>点击按钮执行计算。</p>
<button id="myBtn">点我</button>
<p id="demo"></p>
<script>
var p1 = 5;
var p2 = 7;
document.getElementById("myBtn").addEventListener("click", function() {
myFunction(p1, p2);
});
function myFunction(a, b) {
var result = a * b;
document.getElementById("demo").innerHTML = result;
}
</script>
什么是事件流、事件冒泡、事件捕获?
-
事件流:描述从页面中接受事件的顺序。
HTML元素都位于另一些元素中。当一个元素发生某个事件时,它的父元素同样会发生该事件。
当代码在一个元素和其祖先元素或者后代元素上都有事件处理程序时,事件流就会变得很重要。
事件传递有两种方式:冒泡与捕获。
事件冒泡:指的是事件从最具体的节点开始向外传播到最宽泛的节点。这是事件流的默认类型,被绝大多是浏览器支持。 -
事件捕获:指的是事件从最宽泛的节点开始向内传播到最具体的节点。这种方式在IE8和更早版本的IE中不被支持。
如:事件传递定义了元素事件触发的顺序。 如果你将<p> 元素插入到<div> 元素中
,用户点击<p>
元素, 哪个元素的 “click” 事件先被触发呢?
- 在 冒泡 中,内部元素的事件会先被触发,然后再触发外部元素,即:
<p>
元素的点击事件先触发,然后会触发<div>
元素的点击事件。 - 在 捕获 中,外部元素的事件会先被触发,然后才会触发内部元素的事件,即:
<div>
元素的点击事件先触发 ,然后再触发<p>
元素的点击事件。
//绑定事件
addEventListener(event, function, useCapture);
//"useCapture" 默认值为 false, 即冒泡传递,当值为 true 时, 事件使用捕获传递
removeEventListener()//方法移除由addEventListener()方法添加的事件句柄:
//如果element元素绑定了"mousemove"事件
element.removeEventListener("mousemove", myFunction);
实际开发中我们很少使用事件捕获,我们更关注事件冒泡。
有些事件是没有冒泡的,比如 onblur、onfocus、onmouseenter、onmouseleave
4、IE8 及早期版本支持 attachEvent()、detachEvent()
注意: IE 8 及更早 IE 版本,Opera 7.0及其更早版本不支持addEventListener()
和 removeEventListener()
方法。
但是,对于这类浏览器版本可以使用 detachEvent()
方法来移除事件句柄。
eventTarget.attachEvent(eventNameWithOn, callback)
来绑定事件。
eventTarget.attachEvent()方法将指定的监听器注册到 eventTarget(目标对象) 上,当该对象触发指定的事件时,指定的回调函数就会被执行。
该方法接收两个参数:
- eventNameWithOn:事件类型字符串,比如 onclick 、onmouseover ,这里要带 on
- callback: 事件处理函数,当目标触发事件时回调函数被调用
element.attachEvent(event, function);
element.detachEvent(event, function);
//跨浏览器解决方法:
function addEventListener(element, eventName, fn) {
// 判断当前浏览器是否支持 addEventListener 方法
if (element.addEventListener) {
element.addEventListener(eventName, fn); // 第三个参数 默认是false
} else if (element.attachEvent) {
element.attachEvent('on' + eventName, fn);
} else {
// 相当于 element.onclick = fn;
element['on' + eventName] = fn;
}
四、删除事件(解绑事件)
1. 传统注册方式
eventTarget.onclick = null;
2. 方法监听注册方式
eventTarget.removeEventListener(type, listener[, useCapture]);
eventTarget.detachEvent(eventNameWithOn, callback);
3.删除事件兼容性解决方案
function removeEventListener(element, eventName, fn) {
// 判断当前浏览器是否支持 removeEventListener 方法
if (element.removeEventListener) {
element.removeEventListener(eventName, fn); // 第三个参数 默认是false
} else if (element.detachEvent) {
element.detachEvent('on' + eventName, fn);
} else {
element['on' + eventName] = null;
}
五、事件对象event
官方解释:event 对象代表事件的状态,比如键盘按键的状态、鼠标的位置、鼠标按钮的状态。
简单理解:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象 event,它有很多属性和方法。
这个 event 是个形参,系统帮我们设定为事件对象,不需要传递实参过去。
当我们注册事件时, event 对象就会被系统自动创建,并依次传递给事件监听器(事件处理函数)。
事件对象的兼容性方案
事件对象的常见属性和方法
e.target 和 this 的区别:
-
this 是事件绑定的元素, 这个函数的调用者(绑定这个事件的元素)
-
e.target 是事件触发的元素。
六、阻止事件冒泡的两种方式
阻止事件冒泡的兼容性解决方案
if(e && e.stopPropagation){
e.stopPropagation();
}else{
window.event.cancelBubble = true;
}
七、事件委托(代理、委派)
事件委托也称为事件代理, 在 jQuery 里面称为事件委派。
事件委托的原理
不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。
以上案例:给 ul 注册点击事件,然后利用事件对象的 target 来找到当前点击的 li,因为点击 li,事件会冒泡到 ul 上, ul 有注册事件,就会触发事件监听器。
事件委托的作用
我们只操作了一次 DOM ,提高了程序的性能。