31-JavaScript高级程序设计-事件类型(上)

一、事件类型

1. UI事件

UI(User Interface,用户界面)事件,指的是那些不一定与用户操作有关的事件,当用户与页面上的元素交互时触发。
现有的 UI 事件,多数与 window 对象或表单控件相关。
DOMActivate(废弃)、load、unload、abort、error、select、resize、scroll。

(1)load 事件
  1. 当页面完全加载后(包括所有图像、JavaScript文件、CSS文件等外部资源),就会触发 window 上面的 load 事件。

两种定义 onload 事件处理程序的方式:

  • JavaScript方式 - 使用跨浏览器的 EventUtil 对象
    内部封装 element.addEventListener()、element.attachEvent()、element.onload = xx
EventUtil.addHandler(window, "load", function(event){
  alert("Loaded!");
});

event 对象中不包含有关这个事件的任何附加信息。但在兼容 DOM 的浏览器中,event.target 属性的值会被设置为 document,IE 不会为这个事件设置 srcElement 属性。

  • HTML方式 - 为<body>元素添加一个 onload 特性
<body onload="alert('Loaded!')">
</body>

一般来说,在 window 上面发生的任何事件都可以在<body>元素中通过相应的特性来指定,因为在 HTML 中无法访问 window 元素。

  1. 图像上面也可以触发 load 事件,无论是在 DOM 中的图像元素还是 HTML 中的图像元素。
    (1)HTML 中指定 onload 事件 (2)JavaScript方式
    注意:在指定 src 属性之前先指定事件。新图像元素不一定要从添加到文档后才开始下载,只要设置了 src 属性就会开始下载。
    event.target 属性引用的是<img>元素。

  2. <script>元素也会触发 load 事件,可用于确定动态加载的 JavaScript 文件是否加载完毕。
    浏览器支持:IE9+、Firefox、Opera、Chrome 和 Safari 3+
    注意:指定 src 属性和指定事件处理程序的先后顺序不重要。与图像不同,只有在设置了<script>元素的 src 属性并将该元素添加到文档后,才会开始下载 JavaScript 文件。
    大多数浏览器中 event.target 属性引用的都是<script>节点。

  3. IE 和 Opera 还支持元素上的 load 事件,以便开发人员确定样式表是否加载完毕。
    与<script>节点类似,在未指定 href 属性并将<link>元素添加到文档之前也不会开始下载样式表。

(2)unload 事件

与 load 事件对应的是 unload 事件,这个事件在文档被完全卸载后触发。只要用户从一个页面切换到另一个页面,就会发生 unload 事件。

两种指定 onunload 事件处理程序的方式:

  • JavaScript方式
EventUtil.addHandler(window, "unload", function(event){
  alert("Unloaded");
});

event 对象在兼容 DOM 的浏览器中只包含 target 属性(值为 document)。IE8 及之前版本则为这个事件对象提供了 srcElement 属性。

  • HTML方式
<body onunload="alert('Unloaded!')">
</body>

unload事件注意事项:unload事件是在一切都被卸载之后才触发,那么在页面加载后存在的那些对象,此时就不一定存在。此时,操作 DOM 节点或者元素的样式就会导致错误。

(3)resize 事件

当浏览器窗口被调整到一个新的高度或宽度时,就会触发 resize 事件。
这个事件在 window(窗口)上面触发,因此可以通过 JavaScript 或者<body>元素中的 onresize 特性来指定事件处理程序。

在兼容 DOM 的浏览器中,传入事件处理程序中的 event 对象有一个 target 属性,值为 document;IE8 及之前版本则未提供任何属性。

注意:不要在resize事件的处理程序中加入大计算量的代码,因为这些代码有可能被频繁执行,从而导致浏览器反应明显变慢。

(4)scroll 事件

scroll 事件是在 window 对象上发生的,实际表示的是页面中相应元素的变化。
在混杂模式下,通过<body>元素的 scrollLeft 和 scrollTop 来监控这一变化;
在标准模式下,通过<html>元素来反映这一变化(Safari 仍然基于<body>跟踪滚动位置)。
document.documentElement.scrollTop || document.body.scrollTop
注意:scroll 事件在文档被滚动期间重复被触发 --> 尽量保持事件处理程序的代码简单。

2. 焦点事件

焦点事件在页面元素获得或失去焦点时触发。
与 document.hasFocus() 方法及 document.activeElement 属性配合,可以知晓用户在页面上的行踪。

6 个焦点事件:
获得焦点:focus(不冒泡) focusin(冒泡) DOMFocusIn(冒泡,废弃)
失去焦点:blur(不冒泡) focusout(冒泡) DOMFocusOut(冒泡,废弃)
浏览器支持:
focus和blur:所有浏览器;
focusin和focusout:IE5.5+、Safari 5.1+、Opera 11.5+ 和 Chrome;
DOMFocusIn和DOMFocusOut:Opera,DOM3 级事件已废弃。

当焦点从页面中的一个元素移动到另一个元素,会依次触发下列事件:
(1) focusout 在失去焦点的元素上触发;
(2) focusin 在获得焦点的元素上触发;
(3) blur 在失去焦点的元素上触发;
(4) DOMFocusOut 在失去焦点的元素上触发;
(5) focus 在获得焦点的元素上触发;
(6) DOMFocusIn 在获得焦点的元素上触发。
blur、DOMFocusOut 和 focusout 的事件目标是失去焦点的元素;
focus、DOMFocusIn 和 focusin 的事件目标是获得焦点的元素。

3. 鼠标与滚轮事件

DOM3 级事件中定义了 9 个鼠标事件:

  • click:在用户单击主鼠标按钮(一般是左边的按钮)或者按下回车键时触发。
  • dblclick:在用户双击主鼠标按钮(一般是左边的按钮)时触发。
  • mousedown:在用户按下了任意鼠标按钮时触发。不能通过键盘触发。
  • mouseup:在用户释放鼠标按钮时触发。不能通过键盘触发。
  • mouseenter:在鼠标光标从元素外部首次移动到元素范围之内时触发。这个事件不冒泡,而且在光标移动到后代元素上不会触发。IE、Firefox 9+ 和 Opera 支持。
  • mouseleave:在位于元素上方的鼠标光标移动到元素范围之外时触发。这个事件不冒泡,而且在光标移动到后代元素上不会触发。IE、Firefox 9+ 和 Opera 支持。
  • mousemove:当鼠标指针在元素内部移动时重复地触发。不能通过键盘触发。
  • mouseout:在鼠标指针位于一个元素上方,然后用户将其移入另一个元素时触发。又移入的另一个元素可能位于前一个元素的外部,也可能是这个元素的子元素。不能通过键盘触发。
  • mouseover:在鼠标指针位于一个元素外部,然后用户将其首次移入另一个元素边界之内时触发。不能通过键盘触发。

除了 mouseenter 和 mouseleave,所有鼠标事件都会冒泡,也可以被取消。
取消鼠标事件会影响浏览器的默认行为,还会影响其他事件(鼠标事件与其他事件密不可分)。

双击的事件触发顺序:
(1) mousedown (2) mouseup (3) click (4) mousedown (5) mouseup (6) click (7) dblclick
只有在同一个元素上相继触发 mousedown 和 mouseup 事件,才会触发 click 事件;如果 mousedown 或 mouseup 中的一个被取消,就不会触发 click 事件。
只有触发两次 click 事件,才会触发一次 dblclick 事件。

(1)客户区坐标位置

鼠标事件都是在浏览器视口中的特定位置上发生的。
event.clientXevent.clientY:鼠标事件发生时,鼠标指针在视口中的水平和垂直坐标。(所有浏览器都支持)

(2)页面坐标位置

event.pageXevent.pageY:鼠标事件发生时,鼠标光标在页面中的位置。(IE8 及更早版本不支持)
在页面没有滚动的情况下, pageX 和 pageY 的值与 clientX 和 clientY 的值相等。
event.pageX ? event.pageX : event.clientX + (document.body.scrollLeft || document.documentElement.scrollLeft);

(3)屏幕坐标位置

event.screenXevent.screenY:鼠标事件发生时,鼠标指针相对于整个屏幕的坐标信息。

(4)修改键

鼠标事件主要使用鼠标来触发,在按下鼠标时键盘上的某些键的状态也可以影响到所要采取的操作。
修改键:Shift、Ctrl、Alt 和 Meta(Windows中Windows键,苹果中Cmd键),经常被用来修改鼠标事件的行为。
DOM 规定了 4 个属性(event对象中),表示这些修改键的状态: shiftKey、ctrlKey、altKey、metaKey。按下值为 true,否则值为 false。
浏览器支持:IE9、Firefox、Safari、Chrome、Opera 都支持4个键。IE8 及之前版本不支持 metaKey 属性。

(5)相关元素

相关元素举例:mouseover 事件,事件的主目标是获得光标的元素,相关元素是失去光标的元素。mouseout 事件,事件的主目标是失去光标的元素,相关元素是获得光标的元素。

event.relatedTarget:提供了相关元素的信息。
这个属性只对于 mouseover和 mouseout 事件才包含值;对于其他事件,这个属性的值是 null。
浏览器支持:除IE8及之前版本
IE8-代替属性:mouseover事件 => event.fromElement;mouseout事件 => event.toElement

(6)鼠标按钮

只有在主鼠标按钮被单击(或键盘回车键被按下)时才会触发 click 事件。
mousedown 和 mouseup 事件,有 event.button 属性,表示按下或释放的按钮。
DOM 的 button 属性值:0 - 主鼠标按钮,1 - 中间的鼠标按钮(鼠标滚轮按钮),2 - 次鼠标按钮。
IE8 及之前版本的 button 属性差异较大,最常见做法是将 IE 模型规范化为 DOM 方式。

(7)更多的事件信息

“DOM2 级事件”规范的 event.detail 属性:用于给出有关事件的更多信息。
对于鼠标事件来说, detail 中包含了一个数值,表示在给定位置上发生了多少次单击。如果鼠标在 mousedown 和 mouseup 之间移动了位置,detail 会被重置为 0 。

IE 为鼠标事件提供了更多信息:
altLeft:是否按下了 Alt键。altLeft = true 则 altKey = true。
ctrlLeft:是否按下了 Ctrl 键。ctrlLeft = true 则 ctrlKey = true。
shiftLeft:是否按下了 Shift 键。shiftLeft = true 则 shiftKey= true。
offsetX :光标相对于目标元素边界的 x 坐标。
offsetY :光标相对于目标元素边界的 y 坐标。
用处不大,只有IE支持,有些没有什么价值有些可以计算得到。

(8)鼠标滚轮事件

mousewheel :滚轮事件,用户通过鼠标滚轮与页面交互、在垂直方向上滚动页面时(无论向上还是向下),就会触发。
滚轮事件可以在任何元素上面触发,最终会冒泡到 document(IE8)或 window(IE9、Opera、Chrome、Safari)对象。
mousewheel 事件除了鼠标事件的所有标准信息,还有 event.wheelDelta 属性(向前滚动是120的倍数,向后滚动是-120的倍数)

判断鼠标滚轮滚动方向 --> 检测 wheelDelta 的正负号
注意:Opera 9.5 之前的版本中,wheelDelta 值的正负号是颠倒的。

类似事件:DOMMouseScroll 事件(Firefox)
鼠标滚轮信息保存在 detail 属性中(向前滚动是-3的倍数,向后滚动是3的倍数)
可以将 DOMMouseScroll 事件添加到页面中的任何元素,而且该事件会冒泡到 window 对象。(监听window)

跨浏览器的解决方案:
EventUtil 对象中添加取得鼠标滚轮增量值(delta)的方法。

getWheelDelta: function(event){
  if (event.wheelDelta){
    return (client.engine.opera && client.engine.opera < 9.5 ? -event.wheelDelta : event.wheelDelta);
  } else {
    return -event.detail * 40;
  }
}
(9)触摸设备

iOS 和 Android 设备的实现非常特别,因为这些设备没有鼠标。
在面向 iPhone 和 iPod 中的 Safari 开发时,记住以下几点:

  • 不支持 dblclick 事件。双击浏览器窗口会放大画面,而且没有办法改变该行为。
  • 轻击可单击元素会触发 mousemove 事件。如果此操作会导致内容变化,将不再有其他事件发生;如果屏幕没有因此变化,那么会依次发生 mousedown、mouseup 和 click 事件。轻击不可单击的元素不会触发任何事件。
    可单击的元素是指那些单击可产生默认操作的元素(如链接),或者那些已经被指定了 onclick 事件处理程序的元素。
  • mousemove 事件也会触发 mouseover 和 mouseout 事件。
  • 两个手指放在屏幕上且页面随手指移动而滚动时会触发 mousewheel 和 scroll 事件。
(10)无障碍性问题

无障碍性 – 确保残疾人特别是那些使用屏幕阅读器的人都能访问。
鼠标事件应当注意的几个易访问性问题:

  • 使用 click 事件执行代码。在屏幕阅读器中无法触发 mousedown 事件。
  • 不要使用 onmouseover 向用户显示新的选项。屏幕阅读器无法触发。
  • 不要使用 dblclick 执行重要的操作。键盘无法触发这个事件。

上一篇:30-JavaScript高级程序设计-事件对象
下一篇:32-JavaScript高级程序设计-事件类型(下)

全书整理版:《Javascript高级程序设计》第3版(总结版)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值