JS 13.4.1-13.4.2 UI事件&焦点事件

13.4 事件类型

DOM3级事件:

1.UI(User Interface,用户界面)事件,当用户与页面上的元素交互时触发;

2.焦点事件,当元素获得或失去焦点时触发;

3.鼠标事件,当用户通过鼠标在页面上执行操作时触发;

4.滚轮事件,当使用鼠标滚轮(或类似设备)时触发;

5.文本事件,当在文档中输入文本时触发;

6.键盘事件,当用户通过键盘在页面上执行操作时触发;

7.合成事件,当为IME(Input Method Editor,输入法编辑器)输入字符时触发;

8.变动(mutation)事件,当底层DOM 结构发生变化时触发;

9.变动名称事件,当元素或属性名变动时触发;此类事件已经被废弃,没有任何浏览器实现它们,因此本章不做介绍;

UI事件

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

这些事件在DOM规范出现之前,都是以这种或那种形式存在的,而在DOM规范中保留是为了向后兼容;

到底是哪种,给个痛快话;

DOMActivate,load,unload,abort,error,select,resize,scroll;

能力检测;

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

load事件

根据”DOM2级事件”规范,应该在document而非window上面触发load事件;

但是,所有浏览器都在window上面实现了该事件以确保向后兼容;

// 第一种
EventUtil.addHandler(window, "load", function(event){
    alert("Loaded!");
});

// 第二种
<!DOCTYPE html>
<html>
<head>
<title>Load Event Example</title>
</head>
<body onload="alert('Loaded!')">
</body>
</html>

图像上面也可以触发load事件;

<img src="smile.gif" onload="alert('Image loaded.')">

// 也可以
var image = document.getElementById("myImage");
EventUtil.addHandler(image, "load", function (event) {
    event = EventUtil.getEvent(event);
    alert(EventUtil.getTarget(event).src);
});

在创建新的<img>元素时,可以为其指定一个事件处理程序,以便图像加载完毕后给出提示;

此时,最重要的是要在指定src属性之前先指定事件;

EventUtil.addHandler(window, "load", function () {
    var image = document.createElement("img");
    EventUtil.addHandler(image, "load", function (event) {
        event = EventUtil.getEvent(event);
        alert(EventUtil.getTarget(event).src);
    });
    document.body.appendChild(image);
    image.src = "smile.gif";
});

新图像元素不一定要从添加到文档后才开始下载,只要设置了src属性就会开始下载;

用DOM0级的Image对象实现;

EventUtil.addHandler(window, "load", function () {
    var image = new Image();
    EventUtil.addHandler(image, "load", function (event) {
        alert("Image loaded!");
    });
    image.src = "smile.gif";
});

在DOM出现之前,开发人员经常使用Image对象在客户端预先加载图像;

可以像使用<img>元素一样使用Image对象,只不过无法将其添加到DOM树中;

unload事件

这个事件在文档被完全卸载后触发;

只要用户从一个页面切换到另一个页面,就会发生unload事件;

而利用这个事件最多的情况是清除引用,以避免内存泄漏;

既然unload事件是在一切都被卸载之后才触发,那么在页面加载后存在的那些对象,

此时就不一定存在了;此时,操作DOM节点或者元素的样式就会导致错误;

resize事件

当浏览器窗口被调整到一个新的高度或宽度时,就会触发resize事件;

这个事件在window(窗口)上面触发,

因此可以通过JavaScript或者<body>元素中的onresize特性来指定事件处理程序;

与其他发生在window上的事件类似,在兼容DOM的浏览器中,

传入事件处理程序中的event对象有一个target属性,值为document;

IE,Safari,Chrome和Opera会在浏览器窗口变化了1像素时就触发resize事件,然后随着变化不断重复触发;

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

由于存在这个差别,应该注意不要在这个事件的处理程序中加入大计算量的代码,

因为这些代码有可能被频繁执行,从而导致浏览器反应明显变慢;

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

scroll事件

与resize事件类似,scroll事件也会在文档被滚动期间重复被触发,

所以有必要尽量保持事件处理程序的代码简单;

EventUtil.addHandler(window, "scroll", function (event) {
    if (document.compatMode == "CSS1Compat") {
        alert(document.documentElement.scrollTop);
    } else {
        alert(document.body.scrollTop);
    }
});

焦点事件

焦点事件会在页面元素获得或失去焦点时触发;

blur,DOMFocusIn,DOMFocusOut,focus,focusin,focusout;

这一类事件中最主要的两个是focus和blur,它们都是JavaScript早期就得到所有浏览器支持的事件;

这些事件的最大问题是它们不冒泡;

当焦点从页面中的一个元素移动到另一个元素,会依次触发下列事件:

1.focusout在失去焦点的元素上触发;

2.focusin在获得焦点的元素上触发;

3.blur在失去焦点的元素上触发;

4.DOMFocusOut在失去焦点的元素上触发;

5.focus在获得焦点的元素上触发;

6.DOMFocusIn在获得焦点的元素上触发;

能力检测;

var isSupported = document.implementation.hasFeature("FocusEvent", "3.0");

即使focus和blur不冒泡,也可以在捕获阶段侦听到它们;

至于怎么捕获Peter-Paul Koch就此写过一篇非常棒的文章