JavaScript高级程序设计笔记——事件

事件冒泡

事件冒泡即事件开始时由最具体的元素(最"近"的节点)接收,然后逐级向上传播到较为不具体的节点(文档)

<!DOCTYPE html>
<html>
	<head>
		<title>Click</title>
	</head>
	<body>
		<div id="myDiv">Click Me</div>
	</body>
</html>

以上 HTML 页面中,当点击<div>元素时,click 事件的传递顺序是这样的: div -> body -> html -> document。所有现代浏览器都支持事件冒泡,但具体实现上有差异。

事件捕获

事件捕获的思想是事件开始时由最不具体的元素(最"远"的节点)接收,最具体的元素最后接收到事件。

以之前的 HTML 代码为例,click 事件的传递顺序是这样的:document -> html -> body -> div。老版本的浏览器不支持事件捕获,所以不推荐使用事件捕获。

事件模型

事件的名字包括 click、load 和 mouseover 等,而响应某个事件的函数叫做事件处理程序(或事件侦听器、事件句柄),事件处理程序的名字以"on"开头,为事件指定处理程序的方式有多种。

事件模型分为三种:
●原始事件模型(DOM0级);
●标准事件模型(DOM2级);
●IE事件模型(基本不用了,以下不作描述);

原始事件模型

原始事件模型的特点有:
●绑定速度快,具有很好的跨浏览器优势;
●只支持冒泡,不支持捕获;
●同一个类型的事件只能绑定一次;

绑定方式有以下两种:

1) 方式一

HTML 代码:

<input type="button" value="click" onclick="clickhandle()" />

JavaScript 代码:

function clickHandle() {
	alert("Hello");
}

2) 方式二

HTML 代码:

<input id="btn" type="button" value="click" />

JavaScript 代码:

var btn = document.getElementById("btn");
btn.onclick = function() {
	alert(this.value);
}

事件处理程序中,this 对象引用的是绑定事件处理程序的元素节点。

删除事件处理程序的方法:

btn.onclick = null;

标准事件模型

DOM2 级事件给元素节点定义了addEventListener()removeEventListener()方法,分别用于绑定事件处理程序和删除事件处理程序。这两个方法都接收3个参数:要处理的事件名、作为事件处理程序的绑定函数和一个可选布尔值(默认为 false,通常不需要手动设置),第三个布尔值为 true 表示在捕获阶段调用事件处
IE9以上及其他流行的浏览器都支持 DOM2 级事件处理程序。

HTML 代码:

<input id="btn" type="button" value="click" />

JavaScript 代码:

var btn = document.getElementById("btn");
function clickHandle() {
	alert(this.value);
}

btn.addEventListener("click", clickHandle);

// 5秒后点击按钮将不会有任何反应
setTimeout(function() {
	console.log("Stop");
	btn.removeEventListener("click", clickHandle);
}, 5000);

注意,removeEventListener()第二个参数为具体的事件处理程序函数名,如果需要删除指定事件处理程序,则应先将该事件处理程序定义为普通函数而不是直接使用匿名函数。

事件对象

触发一个事件时,会产生一个事件对象,这个事件对象中包含所有与事件有关的信息。

在事件处理程序中可以访问这个事件对象。

var btn = document.getElementById("btn");
btn.onclick = function(event) {
	alert(event.type); // 输出事件类型: "click"
}

事件对象常用的属性及方法:

  1. e.target:只读,返回事件的目标(直接触发的元素节点);
  2. e.type:只读,返回事件类型;
  3. e.preventDefault():取消事件的默认行为,常用场景有取消提交按钮的点击提交行为及阻止链接点击跳转等,等同于return false;
  4. e.stopPropagation():取消事件进一步捕获或冒泡。

事件类型

UI事件

UI 事件指那些不一定与用户操作有关的事件。

常用的 UI 事件有:

  1. load:页面、图像、脚本等资源完全加载后触发的事件,应用场景:图片加载完全前加入载入一个预备显示图片;
  2. select:用户选择文本框;
  3. scroll:滚动带滚动条的元素时触发,应用场景: 返回顶部按钮。

鼠标事件

鼠标事件是最常用的一类事件。

常用的鼠标事件:

  1. click:单击鼠标左键或按回车键触发;
  2. dblclick:双击鼠标触发;
  3. mousedown:用户按下任意鼠标键时触发;
  4. mouseenter:鼠标移入元素触发;
  5. mouseleave:鼠标移出元素触发;
  6. mousemove:鼠标在元素上移动时触发。

鼠标事件触发元素的事件对象上设置有两个表示客户区(页面显示的区域)坐标的属性:clientX 属性(相对左上角点的水平坐标)和 clientY 属性(相对左上角点的竖直坐标)。

键盘事件

用户使用键盘时会触发键盘事件。

常用的键盘事件:

  1. keydown:按下任意键时触发,按住不放会重复触发;
  2. keypress:按下字符键时触发,按住不放会重复触发;
  3. keyup:释放按键时触发。

键盘事件触发元素的事件对象上设置有 keyCode 属性,用于返回按下的键对应的键码。对于 130事件,触发元素事件对象上的 charCode 属性可以返回按下的字符键对应的 ASCII 码。

自定义事件

var dom = document.getElementById('el');

// 注册事件,不可以添加参数
var eve1 = new Event("myClick")

// 可以添加参数 
var eve2 = new CustomEvent('myClick',params)

// 监听事件
dom.addEventListener("myClick",function () {
	console.log("myClick");
});

// 触发事件
dom.dispatchEvent(eve1);

事件代理

给一个列表中的子项绑定事件处理程序,我们一般会这么做:

// 1. 获取DOM Element
var colorListEl = document.querySelector(".color_list");            
var colors = colorListEl.getElementsByTagName("li");
var box = document.querySelector(".box");            

// 2. 逐个绑定事件处理程序
for (var n = 0; n < colors.length; n++) {                
	colors[n].addEventListener("click", function () {                    
		console.log(this.innerHTML);
		box.innerHTML = "该颜色为 " + this.innerHTML;
	});
}

这种做法在 li 较少的时候可以使用,但如果有一万个 li ,那就会导致性能降低。此时就需要使用事件代理来进行优化了,具体做法是:

function colorChange(e) {                
	var e = e || window.event; // 兼容性的处理

	if (e.target.nodeName.toLowerCase() === "li") {                    
		box.innerHTML = "该颜色为 " + e.target.innerHTML;                
	}                            
}

colorListEl.addEventListener("click", colorChange);

由于事件冒泡机制,点击了 li 后会冒泡到 ul ,此时就会触发绑定在 ul 上的点击事件,再利用 target 找到事件实际发生的元素,就可以达到预期的效果。

使用事件代理的好处不仅在于将多个事件处理函数减为一个,而且对于不同的元素可以有不同的处理方法。假如上述列表元素当中添加了其他的元素节点(如:a、span等),我们不必再一次循环给每一个元素绑定事件,直接修改事件代理的事件处理函数即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值