JavaScript高级程序设计(第3版)学习笔记 第13章

第13章 事件

1.事件:文档或浏览器窗口中发生的一些特定的交互瞬间,可以使用侦听器(或处理程序)来预订事件,以便事件发生时执行相应的代码。

2.事件流:从页面中接收事件的顺序:

  • 事件冒泡(event bubbling):开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。
  • 事件捕获(event capturing):document 对象首先接收到 click 事件,然后事件沿 DOM 树依次向下,一直传播到事件的实际目标。
  • “DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接收到事件。最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。

3.事件处理程序:响应某个事件的函数。

//跨浏览器的事件处理程序,视情况分别使用 DOM0 级方法、DOM2 级方法或 IE 方法来添加事件。
var EventUtil = {
    //添加事件
    addHandler: function(element, type, handler){
        if (element.addEventListener){
            //DOM2 级方法
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent){
            // IE 的方法
            element.attachEvent("on" + type, handler);
        } else {
            //DOM0 级方法
            element["on" + type] = handler;
        }
    },
    //移除事件
    removeHandler: function(element, type, handler){
        if (element.removeEventListener){
            element.removeEventListener(type, handler, false);
        } else if (element.detachEvent){
            element.detachEvent("on" + type, handler);
        } else {
            element["on" + type] = null;
        } 
    }
};

4. 在触发 DOM 上的某个事件时,会产生一个事件对象 event,这个对象中包含着所有与事件有关的信息,包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。

var EventUtil = {
    addHandler: function(element, type, handler){
        //省略的代码 
    },
    //取得对event 对象的引用
    getEvent: function(event){
        return event ? event : window.event;
    },
    //取得事件的目标
    getTarget: function(event){
        return event.target || event.srcElement;
    },
    //取消事件的默认行为
    preventDefault: function(event){
        if (event.preventDefault){
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    },
    removeHandler: function(element, type, handler){
        //省略的代码 
    },
    //阻止事件流
    stopPropagation: function(event){
        if (event.stopPropagation){
            event.stopPropagation();
        } else {
            event.cancelBubble = true;
        } 
    }
};

5..DOM3 级事件”规定了以下几类事件:

  • UI(User Interface,用户界面)事件:当用户与页面上的元素交互时触发。
  • 焦点事件:当元素获得或失去焦点时触发。
  • 鼠标事件:当用户通过鼠标在页面上执行操作时触发。
  • 滚轮事件:当使用鼠标滚轮(或类似设备)时触发。
  • 文本事件:当在文档中输入文本时触发。
  • 键盘事件:当用户通过键盘在页面上执行操作时触发。
  • 合成事件,当为 IME(Input Method Editor,输入法编辑器)输入字符时触发。
  • 变动(mutation)事件,当底层 DOM 结构发生变化时触发。

(1)UI 事件:

  • load:当页面完全加载后在 window 上面触发,当所有框架都加载完毕时在框架集上面触发, 当图像加载完毕时在<img>元素上面触发,或者当嵌入的内容加载完毕时在<object>元素上面 触发。
  • unload:当页面完全卸载后在 window 上面触发,当所有框架都卸载后在框架集上面触发,或者当嵌入的内容卸载完毕后在<object>元素上面触发。
  • abort:在用户停止下载过程时,如果嵌入的内容没有加载完,则在<object>元素上面触发。
  • error:当发生 JavaScript 错误时在 window 上面触发,当无法加载图像时在<img>元素上面触 发,当无法加载嵌入内容时在<object>元素上面触发,或者当有一或多个框架无法加载时在框架集上面触发。
  • select:当用户选择文本框(<input>或<texterea>)中的一或多个字符时触发。
  • resize:当窗口或框架的大小变化时在 window 或框架上面触发。
  • scroll:当用户滚动带滚动条的元素中的内容时,在该元素上面触发。<body>元素中包含所加载页面的滚动条。

(2)焦点事件:

  • blur:在元素失去焦点时触发。这个事件不会冒泡。
  • focus:在元素获得焦点时触发。这个事件不会冒泡。
  • focusin:在元素获得焦点时触发。这个事件与 HTML 事件 focus 等价,但它冒泡
  • focusout:在元素失去焦点时触发。这个事件是 HTML 事件 blur 的通用版本。

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

  • focusout :在失去焦点的元素上触发。
  • focusin :在获得焦点的元素上触发。
  • blur :在失去焦点的元素上触发。
  • focus: 在获得焦点的元素上触发。

(3)鼠标事件:

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

鼠标事件相关属性:

  • clientX 和 clientY 属性:表示鼠标指针在视口中的水平 和垂直坐标。
  • pageX 和 pageY 属性:表示鼠标光标在页面中的位置。在页面没有滚动的情况下,pageX 和 pageY 的值与 clientX 和 clientY 的值相等。
  • screenX 和 screenY 属性:表示鼠标指针相对于整个屏幕的坐标信息。

在按下鼠标的时候时,由于键盘上的某些键的状态也可以影响到操作。键盘上的Shift、Ctrl、Alt 和 Meta(在 Windows 键盘中是 Windows 键,在苹果机中 是 Cmd 键)经常被用来修改鼠标事件的行为。为此DOM规定了 4 个属性,表示修改键的状态:shiftKey、ctrlKey、altKey 和 metaKey。

DOM 通过 event 对象的 relatedTarget 属性提供了相关元素的信息。这个属性只对于 mouseover 和 mouseout 事件才包含值:mouseover 事件:事件的主目标是获得光标的元素,相关元素就是那个失去光标的元素。
mouseout 事件:事件的主目标是失去光标的元素,而相关元素则是获得光标的元素。

var EventUtil = { 
    //省略了其他代码

    //跨浏览器取得相关元素
    getRelatedTarget: function(event){
        if (event.relatedTarget){
             return event.relatedTarget;
        } else if (event.toElement){
            return event.toElement;
        } else if (event.fromElement){
            return event.fromElement;
        } else {
            return null;
        }
    },

    //省略了其他代码 
};
  

 在mousedown 和 mouseup 事件的 event 对象中存在一个 button 属性, 表示按下或释放的按钮。

var EventUtil = { 
    //省略了其他代码

    //跨浏览器取得button属性,
    //返回值0 表示主鼠标按钮,1 表示中间的鼠 标按钮(鼠标滚轮按钮),2 表示次鼠标按钮。
    getButton: function(event){
        if (document.implementation.hasFeature("MouseEvents", "2.0")){
            return event.button;
        } else {
            switch(event.button){
                case 0:
                case 1:
                case 3:
                case 5:
                case 7:
                    return 0;
                case 2:
                case 6:
                    return 2;
                case 4:
                    return 1;
            } 
        }
    },
    
    //省略了其他代码 
};

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

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

(4) 滚轮事件:
mousewheel :在垂直方向上滚动页面时(无论向上还是向下)时触发。

var EventUtil = { 
    //省略了其他代码

    /跨浏览器取得wheelDelta 属性
    getWheelDelta: function(event){
        if (event.wheelDelta){
             return (client.engine.opera && client.engine.opera < 9.5 ?-event.wheelDelta : event.wheelDelta);
        } else {
            return -event.detail * 40;
        }
    },
    //省略了其他代码 
};

(5) 键盘事件:

  • keydown:当用户按下键盘上的任意键时触发,而且如果按住不放的话,会重复触发此事件。
  • keypress:当用户按下键盘上的字符键时触发,而且如果按住不放的话,会重复触发此事件。
  • keyup:当用户释放键盘上的键时触发。

 键盘事件even对象相关属性:

  • keyCode 属性:包含一个代码,与键盘上一 个特定的键对应。
  • charCode 属性:按下的那个键所代表字符的 ASCII 编码。
  • key属性:为了取代 keyCode 而新增的,它的值是一个字符串。在按下某个字符键时,key的值就是相应的文本字符(如“k”或“M”);在按下非字符键时, key 的值是相应键的名(如“Shift” 或“Down”)。
  • char 属性:在按下字符键时的行为与 key 相同,但在按下非字符键时值为 null。
  • keyIdentifier属性:在按下非字符键(例如 Shift)的情况下与 key 的值相同。对于字符键,keyIdentifier 返回一个格式 类似“U+0000”的字符串,表示 Unicode 值。
  • location 的属性:一个数值,表示按下了什么位置上的键: 0 表示默认键盘,1 表示左侧位置(例如左位的 Alt 键),2 表示右侧位置(例如右侧的 Shift 键),3 表示 数字小键盘,4 表示移动设备键盘(也就是虚拟键盘),5 表示手柄(如任天堂 Wii 控制器)。

(6)文本事件:
textInput:当用户在可编辑区域中输入字符时触发。

var textbox = document.getElementById("myText");
EventUtil.addHandler(textbox, "textInput", function(event){ 
    event = EventUtil.getEvent(event);
    //data 属性的值就是用户输入的字符(而非字符编码)
    alert(event.data);
});

textInput事件的event 对象上还有一个属性,叫 inputMethod,表示把文本输入到文本框中的方式。

  • 0:表示浏览器不确定是怎么输入。
  • 1:表示是使用键盘输入的。
  • 2:表示文本是粘贴进来的。
  • 3:表示文本是拖放进来的。
  • 4:表示文本是使用 IME 输入的。
  • 5:表示文本是通过在表单中选择某一项输入的。
  • 6:表示文本是通过手写输入的(比如使用手写笔)。
  • 7:表示文本是通过语音输入的。
  • 8:表示文本是通过几种方法组合输入的。
  • 9:表示文本是通过脚本输入的。

(7) 变动事件:

  • DOMSubtreeModified:在 DOM 结构中发生任何变化时触发。这个事件在其他任何事件触发 10 后都会触发。
  • DOMNodeInserted:在一个节点作为子节点被插入到另一个节点中时触发。
  • DOMNodeRemoved:在节点从其父节点中被移除时触发。
  • DOMNodeInsertedIntoDocument:在一个节点被直接插入文档或通过子树间接插入文档之后触发。这个事件在 DOMNodeInserted 之后触发。
  • DOMNodeRemovedFromDocument:在一个节点被直接从文档中移除或通过子树间接从文档中移除之前触发。这个事件在 DOMNodeRemoved 之后触发。
  • DOMAttrModified:在特性被修改之后触发。
  • DOMCharacterDataModified:在文本节点的值发生变化时触发。

(8)HTML5 事件

  • contextmenu 事件:显示自定义的上下文菜单
  • beforeunload 事件:在浏览器卸载页面之前触发,可以通过它来取消卸载并继续使用原有页面。
  • DOMContentLoaded:在形成完整的 DOM 树之后就会触发, 不理会图像、JavaScript 文件、CSS 文件或其他资源是否已经下载完毕。
  • readystatechange 事件:提供与文档或 元素的加载状态有关的信息,支持 readystatechange 事件的 每个对象都有一个 readyState 属性,可能包含下列 5 个值中的一个:
  1. uninitialized(未初始化):对象存在但尚未初始化。
  2. loading(正在加载):对象正在加载数据。
  3. loaded(加载完毕):对象加载数据完成。
  4. interactive(交互):可以操作对象了,但还没有完全加载。 
  5. ​​​​​​​complete(完成):对象已经加载完毕。
  • pageshow事件:在页面显示时触发,无论该页面是否来自 bfcache。在重新加载的页面中,pageshow 会在 load 事件触发后触发;而对于 bfcache 中的页面,pageshow 会在页面状态完全恢复的那一刻触发。
  • pagehide 事件:在浏览器卸载页面的时候触发,而且是在 unload 事件之前触发。
  • hashchange 事件:在 URL 的参数列表(及 URL 中“#”号后面的所有字符串) 发生变化时触发。

6.事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件,使用事件委托,只需在 DOM 树中尽量最高的层次上添加一个事件处理程序,与采取传统的做法相比具有如下优点:
最适合采用事件委托技术的事件包括 click、mousedown、mouseup、keydown、keyup 和 keypress。

  • document 对象很快就可以访问,而且可以在页面生命周期的任何时点上为它添加事件处理程序 (无需等待 DOMContentLoaded 或 load 事件)。换句话说,只要可单击的元素呈现在页面上,就可以立即具备适当的功能。
  • 在页面中设置事件处理程序所需的时间更少。只添加一个事件处理程序所需的 DOM 引用更少,所花的时间也更少。
  • 整个页面占用的内存空间更少,能够提升整体性能。

7.在测试 Web 应用程序,模拟触发事件是一种极其有用的技术。

(1)DOM中的事件模拟:使用 createEvent()方法创建 event 对象。这个方法接收一个参数,即表示要创建的事件类型的字符串。这个字符串可以是下列几字符串之一:

  • UIEvents:一般化的 UI 事件。鼠标事件和键盘事件都继承自 UI 事件,DOM3 级中是 UIEvent。
  • MouseEvents:一般化的鼠标事件,DOM3 级中是 MouseEvent。
  • KeyboardEvent:DOM3 级中的键盘事件。
  • MutationEvents:一般化的 DOM 变动事件,DOM3 级中是 MutationEvent。
  • HTMLEvents:一般化的 HTML 事件,没有对应的 DOM3 级事件。
  • CustomEvent:DOM3 级中“自定义事件”。
  • //在 DOM 中分派创建的自定义事件对象
    var div = document.getElementById("myDiv"),
        event;
    EventUtil.addHandler(div, "myevent", function(event){
        alert("DIV: " + event.detail);
    });
    EventUtil.addHandler(document, "myevent", function(event){
        alert("DOCUMENT: " + event.detail);
    });
    if (document.implementation.hasFeature("CustomEvents", "3.0")){ 
        event = document.createEvent("CustomEvent"); 
        event.initCustomEvent("myevent", true, false, "Hello world!");
        div.dispatchEvent(event);
    }

     

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值