JS事件—其他常见事件

资源事件

beforeunload 事件

beforeunload事件在窗口、文档、各种资源将要卸载前触发。它可以用来防止用户不小心卸载资源。

如果该事件对象的returnValue属性是一个非空字符串,那么浏览器就会弹出一个对话框,询问用户是否要卸载该资源。但是,用户指定的字符串可能无法显示,浏览器会展示预定义的字符串。如果用户点击“取消”按钮,资源就不会卸载。

window.addEventListener('beforeunload', function (event) {
  event.returnValue = '你确定离开吗?';
});

上面代码中,用户如果关闭窗口,浏览器会弹出一个窗口,要求用户确认。

浏览器对这个事件的行为很不一致,有的浏览器调用event.preventDefault(),也会弹出对话框。IE 浏览器需要显式返回一个非空的字符串,才会弹出对话框。而且,大多数浏览器在对话框中不显示指定文本,只显示默认文本。因此,可以采用下面的写法,取得最大的兼容性。

window.addEventListener('beforeunload', function (e) {
  var confirmationMessage = '确认关闭窗口?';

  e.returnValue = confirmationMessage;
  return confirmationMessage;
});

注意,许多手机浏览器默认忽略这个事件,桌面浏览器也有办法忽略这个事件。所以,它可能根本不会生效,不能依赖它来阻止用户关闭窗口。另外,一旦使用了beforeunload事件,浏览器就不会缓存当前网页,使用“回退”按钮将重新向服务器请求网页。这是因为监听这个事件的目的,一般是修改初始状态,这时缓存初始页面就没意义了。

基本上,只有一种场合可以监听unload事件,其他情况都不应该监听:用户修改了表单,还没有保存就要离开。

unload 事件

unload事件在窗口关闭或者document对象将要卸载时触发。它的触发顺序排在beforeunloadpagehide事件后面。

unload事件发生时,文档处于一个特殊状态。所有资源依然存在,但是对用户来说都不可见,UI 互动全部无效。这个事件是无法取消的,即使在监听函数里面抛出错误,也不能停止文档的卸载。

window.addEventListener('unload', function(event) {
  console.log('文档将要卸载');
});

手机上,浏览器或系统可能会直接丢弃网页,这时该事件根本不会发生。而且跟beforeunload事件一样,一旦使用了unload事件,浏览器就不会缓存当前网页,理由同上。因此,任何情况下都不应该依赖这个事件,指定网页卸载时要执行的代码,可以考虑完全不使用这个事件。

load 事件,error 事件

load事件在页面或某个资源加载成功时触发。注意,页面或资源从浏览器缓存加载,并不会触发load事件。

window.addEventListener('load', function(event) {
  console.log('所有资源都加载完成');
});

error事件是在页面或资源加载失败时触发。abort事件在用户取消加载时触发。

这三个事件实际上属于进度事件,不仅发生在document对象,还发生在各种外部资源上面。浏览网页就是一个加载各种资源的过程,图像(image)、样式表(style sheet)、脚本(script)、视频(video)、音频(audio)、Ajax请求(XMLHttpRequest)等等。这些资源和document对象、window对象、XMLHttpRequestUpload 对象,都会触发load事件和error事件。

session 历史事件

pageshow 事件,pagehide 事件

默认情况下,浏览器会在当前会话(session)缓存页面,当用户点击“前进/后退”按钮时,浏览器就会从缓存中加载页面。

pageshow 事件在页面加载时触发,包括第一次加载和从缓存加载两种情况。如果要指定页面每次加载(不管是不是从浏览器缓存)时都运行的代码,可以放在这个事件的监听函数。

第一次加载时,它的触发顺序排在load事件后面。从缓存加载时,load事件不会触发,因为网页在缓存中的样子通常是load事件的监听函数运行后的样子,所以不必重复执行。同理,如果是从缓存中加载页面,网页内初始化的 JavaScript 脚本(比如 DOMContentLoaded 事件的监听函数)也不会执行。

window.addEventListener('pageshow', function(event) {
  console.log('pageshow: ', event);
});

pageshow 事件有一个persisted属性,返回一个布尔值。页面第一次加载时,这个属性是false;当页面从缓存加载时,这个属性是true

window.addEventListener('pageshow', function(event){
  if (event.persisted) {
    // ...
  }
});

pagehide事件与pageshow事件类似,当用户通过“前进/后退”按钮,离开当前页面时触发。它与 unload 事件的区别在于,如果在 window 对象上定义unload事件的监听函数之后,页面不会保存在缓存中,而使用pagehide事件,页面会保存在缓存中。

pagehide事件实例也有一个persisted属性,将这个属性设为true,就表示页面要保存在缓存中;设为false,表示网页不保存在缓存中,这时如果设置了unload 事件的监听函数,该函数将在 pagehide 事件后立即运行。

如果页面包含