💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] ## 10.4 事件类型 Web浏览器中可能发生的事件又很多类型,不同的事件类型具有不同的信息。 | 事件类型 | 触发时刻 | | --- | --- | | UI | 当用户与页面上的元素交互时触发 | | 焦点 | 当元素获得或失去焦点时触发 | | 鼠标 | 当用户通过鼠标在页面上执行操作时触发 | | 滚轮 | 当使用鼠标滚轮(或类似设备)时触发 | | 文本 | 当在文档中输入文本时触发 | | 键盘 | 当用户通过键盘在页面上执行操作时触发 | | 合成 | 当为IME(输入法编辑器)输入字符时触发 | | 变动 | 当底层DOM结构发生变化时触发 | HTML5也定义了一组事件,而有些浏览器还会在DOM和BOM中实现其他专有事件。 ### 10.4.1 UI事件 UI事件:指不一定与用户操作有关的事件。 **1. load事件** 当页面完全加载后(包括所有图像、JavaScript文件、CSS文件等外部资源),就会触发window上面的load事件。 两种定义onload事件处理程序的方式: * 使用JS代码(推荐) ~~~ EventUtil.addHandler(window,"load",function(event){ alert("Loaded!"); }); ~~~ * 为<body>元素添加一个onload特性(一般,在window上面发生的任何事件都可以在<body>元素中通过相应的特性来指定,因为HTML中无法访问window元素) `<img>`元素也可以 ~~~ <img src="smile.gif" onload="alert('Image loaded.')"> ~~~ **2. unload事件** 在文档被完全卸载后触发,只要用户从一个页面切换到另一个页面,就会发生unload事件。利用这个事件最多的情况是清除引用,以避免内存泄漏。 **3. resize事件** 当浏览器窗口被调整到一个新的高度或宽度时,就会触发。这个事件在window上面触发。 **4. scroll事件** 虽然scroll事件时在window对象上发生的,但它实际表示的则是页面中相应元素的变化。在混杂模式下,可以通过<body>元素的scrollLeft和scrollTop来监控到这一变化;而在标准模式下,除了Safari之外的所有浏览器都会通过<html>元素来反应这一变化。 ### 10.4.2 焦点事件 焦点事件会在页面元素获得或失去焦点时触发。利用这些事件并与document.hasFocus*(方法及document.activeElement属性配合,可以知晓用户在页面上的行踪。 焦点事件发生在Element节点和document对象上。 ||| |---|---| | focus事件 | Element节点获得焦点后触发,该事件不会冒泡。| | blur事件 | Element节点失去焦点后触发,该事件不会冒泡。| | focusin事件 | Element节点将要获得焦点时触发,发生在focus事件之前。该事件会冒泡。Firefox不支持该事件。| | focusout事件 | Element节点将要失去焦点时触发,发生在blur事件之前。该事件会冒泡。Firefox不支持该事件。| * 这四个事件的事件对象,带有target属性(返回事件的目标节点)和relatedTarget属性(返回一个Element节点)。对于focusin事件,relatedTarget属性表示失去焦点的节点;对于focusout事件,表示将要接受焦点的节点;对于focus和blur事件,该属性返回null。 * 由于focus和blur事件不会冒泡,只能在捕获阶段触发,所以addEventListener方法的第三个参数需要设为true。 ### 10.4.3 鼠标与滚轮事件 ||| ||| | click | click事件当用户在Element节点、document节点、window对象上,单击鼠标(或者按下回车键)时触发。“鼠标单击”定义为,用户在同一个位置完成一次mousedown动作和mouseup动作。它们的触发顺序是:mousedown首先触发,mouseup接着触发,click最后触发。| | dblclick | dblclick事件当用户在element、document、window对象上,双击鼠标时触发。该事件会在mousedown、mouseup、click之后触发。| | mousedown | mousedown事件在按下鼠标键时触发。| | mouseup | mouseup事件在释放按下的鼠标键时触发。 | | mousemove | mousemove事件当鼠标在一个节点内部移动时重复地触发。当鼠标持续移动时,该事件会连续触发。为了避免性能问题,建议对该事件的监听函数做一些限定,比如限定一段时间内只能运行一次代码。| | mouseover、mouseenter | 都是鼠标进入一个节点时触发。两者的区别是,mouseenter事件只触发一次,而只要鼠标在节点内部移动,mouseover事件会在子节点上触发多次。| | mouseout、mouseleave | mouseout事件和mouseleave事件,都是鼠标离开一个节点时触发。| 除了“mouseenter”和“mouseleave”外的所有鼠标事件都能**冒泡**。 **1. 客户区坐标位置** 鼠标事件都是在浏览器视口中的特定位置上发生的。这个位置信息保存在事件对象的**clientX和clientY属性**中。所有浏览器都支持这两个属性,他们的值表示事件发生时鼠标指针在视口中的水平和垂直坐标。(不包括页面滚动距离) **2. 页面坐标位置** 页面坐标通过事件对象的**pageX和pageY属性**,表示事件在页面中的什么位置发生。 在页面没有滚动的情况下,pageX和pageY的值与clientX和clientY的值相等。 不支持页面坐标,可使用客户区坐标和滚动信息计算: ~~~ pageX = event.clientX + (document.body.scrollLeft || document.documentElement.scrollLeft); pageY = event.clientY + (document.body.scrollTop || document.documentElement.scrollTop); ~~~ **3. 屏幕坐标位置** 通过screenX和screenY属性就可以确定鼠标事件发生时鼠标指针相对于整个屏幕的坐标信息。 **4. 修改键** DOM规定了4个属性,表示相关修改键的状态:**shifKey、ctrlKey、altKey和metaKey。(布尔值)** **5. 相关元素** 在发生mouseover和mouseout事件时,还会涉及更多的元素。这两个事件都会涉及把鼠标直接从一个元素的边界之内移动到另一个元素的边界之内。 **relatedTarget属性**返回事件的次要相关节点。对于那些没有次要相关节点的事件,该属性返回null。 **6. 鼠标按钮** DOM的button属性 -1:没有按下键。 0:按下主键(通常是左键)。 1:按下辅助键(通常是中键或者滚轮键)。 2:按下次键(通常是右键)。 IE的button属性 返回一个3个比特位的值,表示同时按下了哪些键。它用来处理同时按下多个鼠标键的情况。 1:二进制为001,表示按下左键。 2:二进制为010,表示按下右键。 4:二进制为100,表示按下中键或滚轮键。 同时按下多个键的时候,每个按下的键对应的比特位都会有值。比如,同时按下左键和右键,会返回3(二进制为011)。 **7. 鼠标滚轮事件** * 所有的现代浏览器都支持鼠标滚轮,并在用户滚动滚轮时触发事件。 * 浏览器通常使用鼠标滚轮滚动或缩放文档,但可以通过取消mousewheel事件来阻止这些默认操作。 * 所有浏览器都支持“mousewheel”事件,但Firefox使用“DOMMouseScroll”事件。 *传递给“mousewheel”处理程序的事件对象有**wheelDelta属性**,其指定用户滚动滚轮有多远(根据这个判断滚动方向)。远离用户方向的一次鼠标滚轮“单击”的wheelDelta值通常是120,而接近用户方向的一次“单击”的值是-120。返回的总是120的倍数(120表明mouse向上滚动,-120表明鼠标向下滚动) 而在Firefox中,传递给“DOMMouseScroll”的属性是detail。不过, detail属性值的缩放比率和正负符号不同wheelDelta,detail值乘以-40和wheelDelta值相等。记录其滚动距离的是“detail”属性,它返回的是3的倍数(3表明mouse向下滚动,-3表明mouse向上滚动)。 ~~~ window.onmousewheel = document.onmousewheel = scrollWheel; function scrollWheel(e){ e = e || window.event; if(e.wheelDelta) { //判断浏览器IE,谷歌滑轮事件 if(e.wheelDelta > 0) { //当滑轮向上滚动时 } else if(e.wheelDelta < 0) { //当滑轮向下滚动时 }; } else if(e.detail) { //Firefox滑轮事件 if(e.detail < 0) { //当滑轮向上滚动时 } else if(e.detail > 0) { //当滑轮向下滚动时 }; }; } ~~~ ### 10.4.4 键盘与文本事件 键盘事件用来描述键盘行为,主要有keydown、keypress、keyup三个事件。 **keydown**:按下键盘时触发该事件。 **keypress**:只要按下的键并非Ctrl、Alt、Shift和Meta,就接着触发keypress事件。 **keyup**:松开键盘时触发该事件。 **文本事件textinput**:任何时候,只要用户输入文本都会触发。在Webkit浏览器中支持“textInput”事件。 * 注意:keypress和textinput事件是在新输入的文本真正插入到聚焦的文档元素前触发的。 * 如果用户一直按键不松开,就会重复触发keydown、keypress,直到用户松开才会触发keyup。 **1. 键码** 在发生keydown和keyup事件时,event对象的**keycode属性**指定了输入字符的编码(与ASCII码相同)。 **2. 字符编码** charcode属性,只有发生keypress事件时才包含该值(等于按键字符的ASCII码)。 String.fromCharCode():一个keypress事件表示输入的单个字符。事件对象以数字Unicode编码的形式指定字符,所以必须用String.fromChatCode()把它转换成字符串。 **3. textInput事件** 当用户在可编辑区域中输入字符时,就会触发这个事件。 与keypress事件不同点: * 任何可以获取焦点的元素都可以触发keypress事件,但只有可编辑区域才能触发textInput事件。 * textInput事件只会在用户按下能够输入实际字符的键时才会被触发,而keypress事件则在按下那些能够影响文本显示的键时才会触发(如退格键)。 ### 10.4.5 HTML事件 **1. contextmenu事件** * 用以表示何时应该显示上下文菜单,以便开发人员取消默认的上下文菜单而**提供自定义的菜单**。 * 由于contextmenu事件时冒泡的,因此可以为document指定一个事件处理程序,用以处理页面中发生的所有此类事件。 * 通常使用contextmenu事件来显示自定义的上下文菜单,而是用onclick事件处理程序来隐藏该菜单。 **2. beforeunload事件** 为了让开发人员有可能在页面卸载前阻止这一操作。 **3. DOMContentLoaded事件** 在形成完整的Dom树之后就会触发,不理会图像、JavaScript文件、CSS文件或其他资源是否已经下载完毕。即支持在页面下载的早期添加事件处理程序,意味着用户能够尽早地与页面进行交互。 **4. haschange事件** 便于在URL的参数列表(及URL中“#”号后面的所有字符串)发生变化时通知开发人员。