全面了解 jQuery 事件

650 查看

在一个网页内几乎所有用户交互都可以被 jQuery 作为事件扑捉到。事件具有非常重要的意义,可以让你基于用户动作做出适当的响应。例如,可以写代码改变网页的背景颜色,基于按钮单击或者滚动条滚动事件。

jQuery 有许多快捷方法,像 contextmenu()、hover() 和 keyup(),可以处理不同的事件。除了专门的方法,jQuery 还提供了通用的方法——on(‘eventName’, handler),方便你处理任何事件。牢记一点,这些方法只是在标准 DOM 事件外封装了一层,你可以用原生 JavaScript 来处理这些事件。

在本教程中我们先简单介绍这些事件方法,把这些方法分成五大类,然后来讨论下工作时应遵循的最佳使用方式。

浏览器事件

浏览器事件有三种,分别是 error、resize 和 scroll。像 images 这样的元素没有正确加载的时候会触发 error 事件。该快键方法在 jQuery 1.8 版本中被舍弃了,所以现在应该用 on(‘error’, handler) 方法来代替。

事件

浏览器窗口大小发生变化时会触发 resize 事件。不同浏览器调用 resize 处理方法也不同。Internet Explorer 和 基于 WebKit 的浏览器能够连续的调用处理方法,像 Opera 只能在 resize 事件最后调用。

下面的代码片段是根据窗口宽度改变 image src 属性。

这个 CodePen demo 展示了此事件。

See the Pen The resize event by SitePoint (@SitePoint) on CodePen.

事件

在一个指定的元素中,当用户滚动到不同的位置,可以关闭此事件。除了 window(窗口)对象,任何带 scrollbar 的元素都能触发此事件。例如,所有将 overflow 属性设置为 scroll 的元素,或者任何可滚动的 iframe 可以触发此事件。

the code below, we check if the user has scrolled down more than 500px and perform some actions.

请牢记,scroll 位置发生改变时,将调用处理方法。滚动的原因无关紧要。可能是按了方向键,单击或者拖拽滚动条或者使用了鼠标滚轮。在下面的代码,检查用户向下滚动是否超过 500px,然后触发一些动作。

在下面的 CodePen demo 中,如果一直向下滚动快到底部的时候,应该会看到一条提醒,告诉你接近网页底部了:

See the Pen The scroll event by SitePoint (@SitePoint) on CodePen.

加载事件

基于 document 或 DOM 状态的三种事件,jQuery 有对应的方法,分别是 load、unload 和 ready。

load() 方法可以给任何元素加上一个处理方法,加载一个外部资源,比如图片、脚本、iframes 和 window 对象本身。当元素以及它所有的子元素都加载完该事件被触发。该方法用在图片加载的时候会有些问题。第一个就是 DOM 树无法正确冒泡。第二个问题是不可靠也无法跨浏览器。

当用户离开页面时 unload 事件被触发。用户点击一个链接跳转,在地址栏中输入新的 URL 或者关闭浏览器窗口都能导致此事件发生。还有重新载入页面也会触发。注意,使用 preventDefault() 方法无法取消 unload 事件。此外,在 unload 处理方法中调用 alert()、confirm() 和 prompt() 方法,大多数浏览器都会忽略这几个方法,意味着下面的代码不会运行:

load() 和 unload() 在 1.8 版本中都被废弃了。

The Ready Event

大多数情况下,如图像等所有元素无需完全加载就能正确运行脚本。只要确定 DOM 树构造完就行。ready 事件可以帮你解决。所有 ready 事件的处理方法只有在 DOM 加载完之后才能运行。在处理方法中可以运行 jQuery 代码或者将其他事件处理方法绑定到其他元素上。

下面的 CodePen demo 加载了一张高分辨率图片。你会发现 DOM 在图片完全加载完之前就已经准备好了。

See the Pen The DOM ready event by SitePoint (@SitePoint) on CodePen.

如果代码依赖于一些 CSS 样式属性值,运行之前应该先提供各自引用的样式或嵌入样式。

Keyboard Events

keyboard(键盘) 事件是由用户和键盘之间的交互触发的。每个 keyboard 事件包含按键和事件类型信息。jQuery 中有三个 keyboard 快捷方法——keydown()、keyup() 和 keypress()。

The Keyup and Keydown Events

正如其名,keyup 就是当用户释放键盘上的一个键触发,keydown 就是按住键盘上一个键触发。这些事件的处理方法可以绑定到任何元素上,但是只有当前焦点元素才会被触发。

推荐使用 event 对象中的 which 属性来确定哪个键被按下了。实际上不同浏览器将不同信息存储在这个属性中,jQuery 将 which 属性进行了规范化为了方便可靠的检索此信息。

还有件事需要注意下,这些事件无法区分 a 和 shift+a 。后面的情况 shift 和 a 都是分别注册的。在下面的代码,向用户显示一个弹出框并绑定了 keydown 事件。当按下 y 键,一个指定的元素将会从 DOM 中移除。

See the Pen The keydown event by SitePoint (@SitePoint) on CodePen.

The Keypress Event

keypress 事件和 keydown 事件非常相似。一个主要的区别就是修饰符和一些像 Shift 、Esc 等无法打印的键,不会触发 keypress 事件。不应该用 keypress 事件捕捉像箭头这类的特殊键。当你想知道输入的是哪个字符,比如 A 或者 a ,一般可以使用 keypress 来处理。

下面的代码根据按下的键隐藏一个元素:

See the Pen The keypress event by SitePoint (@SitePoint) on CodePen.

Mouse Events

当用户使用像鼠标这种指点设备时,mouse 事件会被触发。该事件基于点击,如单击、双击和右键快捷菜单或者移动动作,如 mouseenter、mouseleave 和 mousemove。在本节中,将简要地讨论所有这些动作,包括一些演示,说明它们之间的细微差别。

Click-Based Events

jQuery 中定义了五种基于点击事件的方法。mousedown 和 mouseup 事件,从名字上显而易见其意思,当用户在一个元素上分别按住、释放鼠标按键就会触发。另一方面,只有当鼠标按键在指定元素上按住然后释放才会触发点击事件。

dblclick 稍微复杂一点。对于注册为 dblclick 的事件,应该在系统限制时间前快速的点击两次。不能给一个单独的元素同时绑定单击和双击的处理方法,对于双击事件的触发浏览器的处理比较特殊。一些浏览器在双击之前可能会注册两个单独的单击事件,而其他浏览器在双击之前可能只注册一个单击事件。

在一个元素上右键单击,在显示内容菜单前触发 contextmenu 事件。这意味着处理方法中可以用代码阻止显示默认菜单。

下面的代码就阻止了右键单击默认的菜单显示,而是显示了一个自定义菜单。

这个 demo 当图片被点击就会使用新的 CSS 样式,并且有一个自定义内容菜单:

See the Pen The contextmenu event by SitePoint (@SitePoint) on CodePen.

Movement-Based Events

一些事件是基于鼠标指针移动的,进入或离开元素。有六种基于鼠标移动的事件。

让我们从 mouseover 和 mouseenter 事件开始。正如名字的字面意思,当鼠标指针进入一个元素的时候会触发。类似的,鼠标指针离开一个元素 mouseleave 和 mouseout 事件触发。

mouseleave 和 mouseout 之间的一个区别就是前者鼠标指针移出绑定的元素就会触发。后者移出元素的任意后代元素也会触发。mouseenter 和 mouseover 的不同也是一样的(同理与 mouseleave 和 mouseout)。

See the Pen Mouse movement events by SitePoint (@SitePoint) on CodePen.


来看看基于鼠标移动的 mouseenter 和 mouseover 事件是如何计数的。试着从右边进入蓝色的框中,在进入右边粉色的框前停止。 现在 mouseenter 和 mouseover 的值都应该是 1 。如果继续像左移动进入粉色框,mouseover 值变为 2。这是由于 mouseover 事件冒泡引起的。 粉色框的 mouseover 事件冒泡到外面的蓝色框,所以 mouseover 事件计数增加 1。当继续移动停在两个粉色框之间,mouseover 事件再次被触发。到达左边的蓝框时,mouseover
事件计数应该是 5 mouseenter 事件应该仍为 1。

同理可解释 mouseleave 和 mouseout 事件计数。尝试不同方向移动鼠标看看计数如何变化。

The Mousemove and Hover Events

当鼠标指针移入一个元素内 mousemove 事件触发。每当有鼠标移动就会触发,即使移动距离小到只有一个像素。因此,段时间内就可能触发上百次。可以想象,在处理方法中执行复杂的操作会造成浏览器卡顿。明智的做法就是让 mousemove 事件处理方法尽可能高效,当不需要的时候就解除绑定。

当鼠标指针进入并离开元素才会触发 hover。有两种方法调用 hover 方法。第一种是:

当鼠标指针移入元素时执行 handlerIn(),鼠标指针移出时执行 handlerOut()。第二种方法是:

这次鼠标指针移入移出元素时都执行 handlerInOut 方法。

See the Pen The hover and mousemove events by SitePoint (@SitePoint) on CodePen.


注意:该 demo 使用的 CSS 滤镜效果不支持 IE。

Form Events

表单在网络中无所不在。几乎每个用户都填写过一些表单。jQuery 有指定方法专门处理表单事件。 表单值改变或者丢失焦掉都可能触发这些表单事件。有七种表单事件,一个一个来讨论它们。

The Blur, Focus, Focusin and Focusout Events

当一个元素获得焦点就会触发 focus 事件。只适合表单元素和锚标签。想触发其他元素的 focus 事件需要设置元素的 tabindex 属性。记住,在 IE 浏览器中给隐藏元素设置 focus 事件将导致错误。如果一定要触发没有设置 focus 的元素的 focus 事件,可以调用 triggerHandler( “focus” ) 方法。

blur 事件当元素失去焦点时触发。对于老版本的浏览器此事件只适用于表单元素。

不像 focus 事件,focusin 事件无论何时无论什么元素或者它的后代元素获取焦点都能触发。类似的,focusout 当元素或者它的后代元素失去焦点时触发。所以,如果你想利用事件冒泡的话,你应该使用这两个事件。

The Select, Change and Submit Events

当一个元素值改变了会触发 change 事件。此事件只适用于 、 和 元素。在 checkboxes、radio buttons 和 select boxes 情况下,用户做了任何选择就会触发 change 事件。对于其他元素就只有失去焦点的时候才会触发。注意,如果使用 JavaScript 改变 input 元素的值无法触发 change 事件。

当用户在一个元素中选择文本触发 select 事件。此事件范围有限,只适用于 和 元素。如果想要检索所选的文本,需要使用一个跨浏览器 jQuery 插件。

当用户要提交表单时触发 submit 事件。只能将处理方法绑定在表单元素上。用户点击 、 或者 元素时会触发该事件。有趣的是在 IE 浏览器中 JavaScript submit 事件不会冒泡。不过,这个行为在 jQuery 1.4 版本中已经做了跨浏览器规范化。

See the Pen Form events by SitePoint (@SitePoint) on CodePen.

Changes in jQuery 3

load、error 和 unload 方法已经在 jQuery 1.8 版本中舍弃。load() 方法本质上不太明确。这个方法既可以是 AJAX 加载或者是普通加载事件。类似的,error 方法和 jQuery.error() 方法会混淆。现在 jQuery 3 中这些方法最终被移除。现在必须给这些方法注册监听器来使用。

Final Thoughts

在这篇文章中,基本上覆盖了所有 jQuery 主要的事件方法,还有这些事件之间的差异和相同之处。知道什么时候使用 keypress 代替 keydown 可以帮助你避免麻烦和节省宝贵的时间。尽管可以用原生的 JavaScript 在 DOM 事件中添加 hook,jQuery 对跨浏览器的一些差异做了规范化,意味着网站、应用能支持更多浏览器,这是一个优势。

想了解更多事件可以访问 jQuery 官方文档。如果有关于 jQuery 使用中的任何问题或建议,请发表评论。