这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战
HTML5
详尽地列出了浏览器支持的所有事件。下面会介绍浏览器较好支持的事件,但也并不是所有浏览器支持。
1. contextmenu 事件
contextmenu
事件,以专门用于表示何时该显示上下文菜单,从而允许开发者取消默认的上下文菜单并提供自定义菜单。contextmenu
事件冒泡,因此只要给 document
指定一个事件处理程序就可以处理页面上的所有同类事件。contextmenu
事件应该算一种鼠标事件,因此 event
对象上的很多属性都与光标位置有关。来看下面的例子:
<!DOCTYPE html>
<html>
<head>
<title>ContextMenu Event Example</title>
</head>
<body>
<div id="myDiv">
Right click or Ctrl+click me to get a custom context menu. Click anywhere else to get the default context menu.
</div>
<ul
id="myMenu"
style="position: absolute; visibility: hidden; background-color: silver"
>
<li><a href="http://www.somewhere.com"> somewhere</a></li>
<li><a href="http://www.wrox.com">Wrox site</a></li>
<li><a href="http://www.somewhere-else.com">somewhere-else</a></li>
</ul>
<script>
window.addEventListener("load", (event) => {
let div = document.getElementById("myDiv");
div.addEventListener("contextmenu", (event) => {
event.preventDefault(); // 阻止默认菜单的展示
// 展示自定义的菜单
let menu = document.getElementById("myMenu");
menu.style.left = event.clientX + "px";
menu.style.top = event.clientY + "px";
menu.style.visibility = "visible";
});
document.addEventListener("click", (event) => {
document.getElementById("myMenu").style.visibility = "hidden";
});
});
</script>
</body>
</html>
2. beforeunload 事件
beforeunload
事件会在 window
上触发,用意是给开发者提供阻止页面被卸载的机会。这个事件会在页面即将从浏览器中卸载时触发,我们可以在页面被卸载的时候做一些我们需要做的事情。当然一般我们是不希望用户关闭页面的,所以我们会给提示框。
类似下面的代码:
window.addEventListener("beforeunload", (event) => {
let message = "I'm really going to miss you if you go.";
event.returnValue = message; // 针对IE和Firefox
return message; // 针对safari和chrome
});
3. DOMContentLoaded 事件
window
的 load
事件会在页面完全加载后触发。而 DOMContentLoaded
事件会在 DOM
树构建完成后立即触发,不用等待图片、JavaScript
文件、CSS
文件或其他资源加载完成。相对于 load
事件,DOMContentLoaded
可以让开发者在外部资源下载的同时就能指定事件处理程序,从而让用户能够更快地与页面交互。
下面是一个简单的例子:
document.addEventListener("DOMContentLoaded", (event) => {
console.log("Content loaded");
});
DOMContentLoaded
事件的 event
对象中不包含任何额外信息(除了 target
等于 document
)。
4. readystatechange 事件
支持 readystatechange
事件的每个对象都有一个 readyState
属性,该属性具有一个以下列出的可能的字符串值。
uninitialized
: 对象存在并尚未初始化。loading
: 对象正在加载数据。loaded
: 对象已经加载完数据。interactive
: 对象可以交互,但尚未加载完成。complete
: 对象加载完成。
在 document
上使用时,值为interactive
的 readyState
首先会触发 readystatechange
事件,时机类似于 DOMContentLoaded
。进入交互阶段,意味着 DOM
树已加载完成,因而可以安全地交互了。下面是一个使用例子:
document.addEventListener("readystatechange", (event) => {
if (document.readyState == "interactive") {
console.log("Content loaded");
}
});
在包含特别多或较大外部资源的页面中,交互阶段会在 load
事件触发前先触发。而在包含较少且较小外部资源的页面中,这个 readystatechange
事件有可能在 load
事件触发后才触发。
document.addEventListener("readystatechange", (event) => {
if (
document.readyState == "interactive" ||
document.readyState == "complete"
) {
document.removeEventListener("readystatechange", arguments.callee);
console.log("Content loaded");
}
});
先检测 readyState
的状态是不是可交互或者已完成,如果是的话,就移除事件监听。注意,因为这里的事件处理程序是匿名函数,所以使用了 arguments.callee
作为函数指针。
在 MDN
对这个事件是这样描述的:
当文档的
readyState
属性发生改变时,会触发readystatechange
事件。
在给出的例子中,是对 load
、readystatechange
和 DOMContentLoaded
这三个事件的先后顺序做了个测试。
执行后的结果依次是:
readystate: interactive
DOMContentLoaded
readystate: complete
load
5. pageshow 与 pagehide 事件
pageshow
:其会在页面显示时触发,无论是否来自往返缓存。在新加载的页面上,pageshow
会在 load 事件之后触发;在来自往返缓存的页面上,pageshow
会在页面状态完全恢复后触发。
下面来看一个例子:
(function() {
let showCount = 0;
window.addEventListener("load", () => {
console.log("Load fired");
});
window.addEventListener("pageshow", () => {
showCount++;
console.log(`Show has been fired ${showCount} times.`, `Persisted? ${event.persisted}`); // persisted: 如果页面存储在了往返缓存中就是 true,否则就是 false。
});
})();
这边用了一个闭包,把每次进入页面的 showCount
记录下来。每次进入页面都会记录进入的次数。除非刷新页面。
与 pageshow
对应的事件是 pagehide
,这个事件会在页面从浏览器中卸载后,在 unload
事件之前触发。
window.addEventListener("pagehide", (event) => {
console.log("Hiding. Persisted? " + event.persisted);
});
对pageshow
事件来说,persisted
为 true
表示页面是从往返缓存中加载的;而对 pagehide
事件来说,persisted
为 true
表示页面在卸载之后会被保存在往返缓存中。
6. hashchange 事件
HTML5
增加了 hashchange
事件,用于在 URL
散列值(URL
最后#
后面的部分)发生变化时通知开发者。这是因为开发者经常在 Ajax
应用程序中使用 URL
散列值存储状态信息或路由导航信息。
event
对象有两个新属性:oldURL
和 newURL
。这两个属性分别保存变化前后的 URL
,而且是包含散列值的完整 URL
。下面的例子展示了如何获取变化前后的 URL
:
window.addEventListener("hashchange", (event) => {
console.log(`Old URL: ${event.oldURL}, New URL: ${event.newURL}`);
});
// 如果想确定当前的散列值,最好使用 location 对象:
window.addEventListener("hashchange", (event) => {
console.log(`Current hash: ${location.hash}`);
});