JS高级程序设计——第13章事件 13.4 事件类型(UI、焦点)

一、事件的类型

  1. 如前所述,不同的事件类型具有不同的信息,而**“DOM3 级事件”规定了**以下几类事件。
    在这里插入图片描述
  2. 除了这几类事件之外,HTML5 也定义了一组事件,而有些浏览器还会在 DOM 和 BOM 中实现其他专有事件。这些专有的事件一般都是根据开发人员需求定制的,没有什么规范,因此不同浏览器的实现有可能不一致。
  3. DOM3 级事件模块在 DOM2 级事件模块基础上重新定义了这些事件,也添加了一些新事件。包括 IE9 在内的所有主流浏览器都支持 DOM2 级事件。IE9 也支持 DOM3 级事件。

二、UI事件

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

1、现有的UI事件
  1. 多数这些事件都与 window 对象或表单控件相关。
    在这里插入图片描述
    在这里插入图片描述
    除了 DOMActivate 之外,其他事件在 DOM2 级事件中都归为 HTML 事件(DOMActivate 在 DOM2级中仍然属于 UI 事件)。

  2. 确定浏览器是否支持 DOM2 级事件规定的 HTML 事件,可以使用如下代码:

    var isSupported = document.implementation.hasFeature("HTMLEvents", "2.0");
    

    注意,只有根据“DOM2 级事件”实现这些事件的浏览器才会返回 true。而以非标准方式支持这些事件的浏览器则会返回 false。

  3. 确定浏览器是否支持“DOM3 级事件”定义的事件,可以使用如下代码:

var isSupported = document.implementation.hasFeature("UIEvent", "3.0");
2、load事件
  1. 页面完全加载后(包括所有图像、JavaScript 文件、 CSS 文件等外部资源),就会触发 window 上面的 load 事件
  2. 两种定义 onload 事件处理程序的方式
  • 第一种方式是使用如下所示的 JavaScript 代码:
    在这里插入图片描述
    与添加其他事件一样,这里也给事件处理程序传入了一个 event 对象。这个 event 对象中不包含有关这个事件的任何附加信息,但在兼容 DOM 的浏览器中,event.target 属性的值会被设置为 document,而 IE 并不会为这个事件设置 srcElement 属性。【不理解,为什么不包含?自测打印是包含的。】
  • 第二种指定 onload 事件处理程序的方式是为<body>元素添加一个 onload 特性,如下面的例子 所示:
<!DOCTYPE html>
<html>
<head>
     <title>Load Event Example</title>
</head>
<body onload="alert('Loaded!')">
</body>
</html>

一般来说,在 window 上面发生的任何事件都可以在<body>元素中通过相应的特性来指定,因为在 HTML 中无法访问 window 元素【元素无法获取只能取得window对象】。实际上,这只是为了保证向后兼容的一种权宜之计,但所有浏览器 都能很好地支持这种方式。我们建议读者尽可能使用 JavaScript 方式。

  1. 图像上面也可以触发 load 事件,无论是在 DOM 中的图像元素还是 HTML 中的图像元素。因此, 可以在 HTML 中为任何图像指定 onload 事件处理程序,例如:
 <img src="smile.gif" onload="alert('Image loaded.')">

这样,当例子中的图像加载完毕后就会显示一个警告框。

  • 同样的功能也可以使用 JavaScript 来实现, 例如:
    在这里插入图片描述
    这里,使用 JavaScript 指定了 onload 事件处理程序。同时也传入了 event 对象,尽管它也不包含什么有用的信息【又一次提到?难道是因为load事件就这样图书吗?】。不过,事件的目标是<img>元素,因此可以通过 src 属性访问并显示该信息。

  • 在创建新的<img>元素时,可以为其指定一个事件处理程序,以便图像加载完毕后给出提示。此时, 最重要的是要在指定 src 属性之前先指定事件,如下面的例子所示。
    在这里插入图片描述
    在这个例子中,首先为 window 指定了 onload 事件处理程序。原因在于,我们是想向 DOM 中添 加一个新元素,所以必须确定页面已经加载完毕——如果在页面加载前操作 document.body 会导致错误。

    然后,创建了一个新的图像元素,并设置了其 onload 事件处理程序。最后又将这个图像添加到页面中,还设置了它的 src 属性。

    这里有一点需要格外注意:新图像元素不一定要从添加到文档后才开始下载,只要设置了 src 属性就会开始下载

  1. 同样的功能也可以通过使用 DOM0 级的 Image 对象实现。在 DOM出现之前,开发人员经常使用 Image 对象在客户端预先加载图像。可以像使用<img>元素一样使用 Image 对象,只不过无法将其添加到 DOM 树中。下面来看一个例子。
    在这里插入图片描述
    在此,我们使用 Image 构造函数创建了一个新图像的实例,然后又为它指定了事件处理程序。有的浏览器将 Image 对象实现为<img>元素,但并非所有浏览器都如此,所以最好将它们区别对待

不属于DOM文档的图像(包括未添加到文档的<img>元素和Image对象)上触发load事件时,IE8及之前版本不会生成event对象,IE9修复了这个问题。

  1. 还有一些元素也以非标准的方式支持 load 事件。在 IE9+、Firefox、Opera、Chrome 和 Safari 3+及 更高版本中,<script>元素也会触发 load 事件,以便开发人员确定动态加载的 JavaScript 文件是否加载完毕
  • 与图像不同,只有在设置了<script>元素的 src 属性并将该元素添加到文档后,才会开始下 载 JavaScript 文件。换句话说,对于<script>元素而言,指定 src 属性和指定事件处理程序的先后顺序就不重要了【图像是只要设置了src属性就会开始下载,如果在指定src之后再指定事件处理顺序,那时图像可能已经加载完,事件监听不到,无法触发事件】。以下代码展示了怎样为<script>元素指定事件处理程序。
    在这里插入图片描述
    这个例子使用了跨浏览器的 EventUtil 对象为新创建的<script>元素指定了 onload 事件处理程序。此时,大多数浏览器中 event 对象的 target 属性引用的都是<script>节点,而在 Firefox 3 之前 的版本中,引用的则是 document。IE8 及更早版本不支持<script>元素上的 load 事件。
  1. IE 和 Opera 还支持<link>元素上的 load 事件,以便开发人员确定样式表是否加载完毕。例如:
    <script>节点类似,在未指定 href 属性并将<link>元素添加到文档之前也不会开始下载样式表。
    在这里插入图片描述
3、unload事件
  1. 与 load 事件对应的是 unload 事件,这个事件在文档被完全卸载后触发只要用户从一个页面切换到另一个页面,就会发生 unload 事件。而利用这个事件最多的情况是清除引用,以避免内存泄漏
  2. 与 load 事件类似,也有两种指定 onunload 事件处理程序的方式
  • 第一种方式是使用 JavaScript,如下所示:
    在这里插入图片描述
    此时生成的 event 对象在兼容 DOM 的浏览器中只包含 target 属性(值为document)。IE8 及之前版本则为这个事件对象提供了 srcElement 属性。【只有unload中的事件对象提供了srcELement属性吗?】
  • 指定事件处理程序的第二种方式,也是为<body>元素添加一个特性(与 load 事件相似),如下面的例子所示:
    在这里插入图片描述
    无论使用哪种方式,都要小心编写onunload事件处理程序中的代码。既然unload事件是在一切都被卸载之后才触发,那么在页面加载后存在的那些对象,此时就不一定存在了。此时,操作 DOM 节点或者元素的样式就会导致错误。

根据“DOM2 级事件”,应该在<body>元素而非 window 对象上面触发 unload 事件。不过,所有浏览器都在 window 上实现了 unload 事件,以确保向后兼容。

4、resize 事件
  1. 当浏览器窗口被调整到一个新的高度或宽度时,就会触发 resize 事件。这个事件在 window(窗口)上面触发,因此可以通过 JavaScript 或者<body>元素中的 onresize 特性来指定事件处理程序。如前所述,我们还是推荐使用如下所示的 JavaScript 方式:
EventUtil.addHandler(window, "resize", function(event){
        alert("Resized");
});

与其他发生在 window 上的事件类似,在兼容 DOM 的浏览器中,传入事件处理程序中的 event 对 象有一个 target 属性,值为 document;而 IE8 及之前版本则未提供任何属性

  • 关于何时会触发 resize 事件,不同浏览器有不同的机制。
    IE、Safari、Chrome 和 Opera 会在浏览器窗口变化了 1 像素时就触发 resize 事件,然后随着变化不断重复触发

    Firefox 则只会在用户停止调 整窗口大小时才会触发 resize 事件

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

    浏览器窗口最小化或最大化时也会触发 resize 事件。

5、scroll事件

虽然 scroll 事件是在 window 对象上发生的,但它实际表示的则是页面中相应元素的变化。在混杂模式下,可以通过<body>元素的 scrollLeft 和 scrollTop 来监控到这一变化;而在标准模式下, 除 Safari 之外的所有浏览器都会通过<html>元素来反映这一变化(Safari 仍然基于<body>跟踪滚动位 置),如下面的例子所示
在这里插入图片描述
以上代码指定的事件处理程序会输出页面的垂直滚动位置——根据呈现模式不同使用了不同的元 素。由于 Safari 3.1 之前的版本不支持 document.compatMode,因此旧版本的浏览器就会满足第二个条件。

与 resize 事件类似,scroll 事件也会在文档被滚动期间重复被触发,所以有必要尽量保持事件 处理程序的代码简单

三、焦点事件

  1. 焦点事件会在页面元素获得或失去焦点时触发。利用这些事件并与 document.hasFocus()方法及 document.activeElement 属性配合,可以知晓用户在页面上的行踪。有以下 6 个焦点事件。
    在这里插入图片描述
    在这里插入图片描述
  • 这一类事件中最主要的两个是 focus 和 blur,它们都是 JavaScript 早期就得到所有浏览器支持的事件。这些事件的最大问题是它们不冒泡。因此,IE 的 focusin 和 focusout 与 Opera 的 DOMFocusIn 和 DOMFocusOut 才会发生重叠。IE 的方式最后被 DOM3 级事件采纳为标准方式。
  1. 当焦点从页面中的一个元素移动到另一个元素加粗样式,会依次触发下列事件:
    (1) focusout 在失去焦点的元素上触发;
    (2) focusin 在获得焦点的元素上触发;
    (3) blur 在失去焦点的元素上触发;
    (4) DOMFocusOut 在失去焦点的元素上触发;
    (5) focus 在获得焦点的元素上触发;
    (6) DOMFocusIn 在获得焦点的元素上触发。
    其中,blur、DOMFocusOut和focusout的事件目标是失去焦点的元素;而focus、DOMFocusIn和 focusin 的事件目标是获得焦点的元素
  2. 确定浏览器是否支持这些事件,可以使用如下代码:
var isSupported = document.implementation.hasFeature("FocusEvent", "3.0");
  1. 即使 focus 和 blur 不冒泡,也可以在捕获阶段侦听到它们
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值