0%

EJ15

处理事件

一些程序和直接的用户输入打交道,如鼠标和键盘行为。那种类型的输入不能作为一个组织良好的数据结构获得——它实时的一块接一块的到来,并且程序被期望随时响应。

事件处理器

想象一个接口,其中唯一的检测是否键盘上某一按键被按下的方式就是读取那个键的当前状态。为了能够响应按键,你必须持续读取那个键的状态,如此一来你就能在它释放之前捕捉到它。执行其他时间密集型的计算是危险的因为你可能错过按键。

一些基本的机器确实像这样处理输入。从这一步开始,硬件或者操作系统注意到按键操作并将其放到一个队列。程序就可以为新事件周期性检查队列并对发现的事情作出反应。

当然,它必须记住查看队列,并且经常这样做,因为在按键被按下和程序注意到事件之间的任何时间,都将导致软件感觉没有响应。这种方法叫做轮询。大多数的开发人员倾向于避免它。

一个更好的机制就是当事件发生的时候,系统主动通知我们的代码。浏览器通过允许我们将函数注册为特定事件的处理器来实现这个。

1
2
3
4
5
6
<p>Click this document to activate the handler.</p>
<script>
window.addEventListener("click", () => {
console.log("You knocked?");
});
</script>

window绑定指的是浏览器提供的内建对象。它代表了包含文档的浏览器窗口。调用它的addEventListener方法使得第一个参数事件发生的时候,第二个参数被调用。

事件和DOM节点

每个浏览器事件处理器都在上下文中注册。在前面的例子中,我们在window对象上调用addEventListener来为整个窗口注册一个处理器。这样的方法也能在DOM元素和其它类型的对象上发现。事件监听器只在事件发生在所注册对象的上下文中发生时才会调用。

1
2
3
4
5
6
7
8
<button>Click me</button>
<p>No handler here.</p>
<script>
let button = document.querySelector("button");
button.addEventListener("click", () => {
console.log("Button clicked.");
});
</script>