android CheckBox 改选中颜色_checkbox选中触发事件


在前面的两篇文章中,已经介绍了事件的传达机制,以及如何阻止事件的冒泡与默认的行为。 那么,作为「事件三部曲」的最后一篇,我们就来大概介绍一下,DOM 规范之中究竟提供了哪些事件。

事件的种类

浏览器可能发生的事件有很多种,了解这些事件的情境及效果,是 Web 开发不能忽略的基础,接下来介绍一下常见的几种事件:

界面相关事件

界面相关的事件不一定会与使用者对 DOM 的操作有关系,反而大多数与window对象比较有关系。

  • load 事件:

注册在 window 对象上,指的是在页面或某个资源加载成功时触发。注意,页面或资源从浏览器缓存加载,并不会触发load事件。


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


  • unloadbeforeunload 事件:

与 load 事件相反,unload 与 beforeunload 事件分别会在离开页面或重新整理时触发,而 beforeunload 会跳出对话框询问使用者是否要离开当前页面。


android CheckBox 改选中颜色_iframe src更改事件检测?_02


  • error 事件:

error 事件会在 document 或是图片载入错误时触发。由于考虑到维护性,大多事件的注册我会强烈建议使用「非侵入式 JavaScript」的写法,即JavaScript代码和标记的分离。只有 error 事件最适合以 on-event 的写法来处理:


<img src="image.jpg" onerror="this.src='default.jpg'">


像这样,当image.jpg这张图片不存在的时候,马上就会触发error事件,就会通过this.src<img>的 src 属性替换成指定的图片,是相当实用的技巧。

若是在网页 load 完成后才注册了error事件,你只会看到破图的结果,因为error事件不会再次被触发,后来挂上去的事件处理函数就等于没有一样。

  • resize事件:在改变浏览器窗口大小时触发,主要发生在window对象上面。
  • scroll事件:在文档或文档元素滚动时触发,主要出现在用户拖动滚动条。
  • DOMContentLoaded事件:

类似于load事件,但不同的是,load事件是在网页「所有」资源都已经载入完成后才会触发,而DOMContentLoaded事件是在 DOM 结构被完整的读取跟解析后就会被触发,不须等待外部资源读取完成,因此可以这么说,这两者所监听的阶段不同,可以用下面这张图来解释:


android CheckBox 改选中颜色_input 事件_03


我们在《通过DOM API 查找节点》这篇文章中曾介绍过,<script>标签要是放在<head> ... </head>之间,因为还没解析到网页本体会有选取不到 DOM 的问题对吧?


<html>
<head>
  <script>
    // 因 Document 结构未载入,无效
    document.getElementById('hello').textContent = 'Hello';
  </script>
</head>
<body>
  <div id="hello"></div>
</body>
</html>


那么,改成这样:


<html>
<head>
  <script>
    document.addEventListener("DOMContentLoaded", function() {
      // 当 document 结构已解析完成才会执行
      document.getElementById('hello').textContent = 'Hello';
    }, false);
  </script>
</head>
<body>
  <div id="hello"></div>
</body>
</html>


就可以排除<script>标签放在<head> ... </head>抓不到 DOM 的问题啦。

与大家所熟知的 jQuery$( document ).ready( handler )作用类似。

鼠标相关事件

  • mousedown / mouseup 事件: 这两个事件分别会在鼠标点击了某元素「按下」(mousedown) 按钮,以及「放开」(mouseup)按钮时触发。
  • click 事件: 当鼠标「点击」了某元素时触发。
  • dblclick事件: 当鼠标「连点两次」某元素时触发。
  • mouseenter / mousemove / mouseleave 事件:这三个事件要放在一起看:
  1. 当鼠标光标移入了某元素时,会先触发 mouseenter 事件。
  2. 鼠标光标在这个元素內「移动」时,会连续触发 mousemove 事件。
  3. 直到鼠标光标离开了这个元素,才触发 mouseleave 事件。


android CheckBox 改选中颜色_iframe src更改事件检测?_04


这些鼠标相关的事件,都可以通过event.pageX 与 event.pageY属性去取得目前鼠标在网页对应的坐标。

键盘相关事件

键盘常用相关事件有下列三种,在大多数情况下会将键盘事件注册在 input 的输入框上。

  • keydown 事件: 「压下」键盘按键时会触发 keydown 事件。
  • keypress 事件: 除了 Shift, Fn, CapsLock 这三种按键外按住时会触发,若按着不放则会连续触发。
  • keyup 事件: 「放开」键盘按键时会触发。

如果我们针对同个元素同时绑定了这三个键盘事件,那么这三个事件执行的顺序会是:


keydown
keypress
keyup


若此时想要知道使用者按下的按键是哪个,则可以通过event.keyCode属性来查询。keyCode的对应表可以到这里查看:

例如,今天你想要当使用者在input输入框按下 「enter」 时,发动submit,就可以这样做:


textBox.addEventListener('keydown', function(e){
  // enter 的 keyCode 是 13
  if( e.keyCode === 13 ){
    formSubmit();
  }
}, false);


像这样,通过e.keyCode就可以判断使用者目前按下的是哪个按钮。

表单相关事件

  • input 事件: 当 inputtextarea 以及带有 contenteditable 的元素內容被改变时,就会触发 input 事件。
  • change 事件: 当 inputselecttextarearadiocheckbox 等表单元素被改变时触发。 但与 input 事件不同的是,input 事件会在输入框输入內容的当下触发,而 change 事件则是在目前焦点离开输入框后才触发。
  • submit 事件:当表单被送出时触发,通常表单验证都会在这一步处理,若验证未通过则 return false;
  • focus 事件:当元素被聚焦时触发。
  • blur 事件:当元素失去焦点时触发。

特殊事件

  • Composition Event (组成事件):

Composition Event 其实指的是 compositionstartcompositionend ,以及 compositionupdate 这三个事件。

介绍 Composition Events 之前先来谈谈 DOM API 过去对输入框侦测变化的几个方式:

常见的表单输入框如: <input type="text"> 如果要动态监听输入框的文字变化时, 大多会通过监听 keydownkeypresskeyup 等键盘事件来判断 value 是否变动,但如果是通过「复制粘贴」之类的操作,就无法通过键盘事件来判断。

而即使是 change 事件则是要在使用者改变內容,且焦点离开输入框的前一刻才会被触发。

所以后来有了 input 事件, input 事件会在输入框的內容被改变时即时触发,确实也解决了过去在 onChange 以及键盘相关事件功能不足所产生的问题。

但是,新的问题来了!

通常像这样的搜索框,我们会用类似 autocomplete (自动完成) 的方式给使用者搜索建议 (以 google 为例):


android CheckBox 改选中颜色_input 输入事件_05


如上图,在输入中文的时候,通常会需要通过注音之类的输入法来做拼字。

但是在大部分的情況下,针对「注音符号」或是「拼音文字」去给搜索建议是没有太大意义的。

这个时候就需要通过 Composition Events 来为输入框做增强。

通过 Composition Events 我们可以观察使用者在输入框內开启输入法 (Input Method Editor, IME) 时,组字或选字的状态。

Composition Events 提供三个事件给开发者监听:分別是 compositionstartcompositionend ,以及 compositionupdate

  • compositionstart: 输入框內开启输入法,且正在拼字时触发。
  • compositionupdate: 输入框內开启输入法,且正在拼字选字时更改了內容时触发。
  • compositionend: 输入框內开启输入法,拼字或选字完成,正要送出至输入框时触发。

执行的时候像这样:


android CheckBox 改选中颜色_html页面加载完成后会触发的事件_06


可以看到,如果要确认使用者输入完成并送出文字时,就可以通过compositionend来做最后确认。

自订事件

自订事件可以用Event constructor建立,同样通过addEventListener去监听,由dispatchEvent决定触发的时间。


var event = new Event('build');

// 监听事件
elem.addEventListener('build', function (e) { ... }, false);

// 触发事件
elem.dispatchEvent(event);


若是想要在自订事件內增加更多资料,则可以改用CustomEvent


var event = new CustomEvent('build', { 'detail': elem.dataset.time });


那么在 Event 处理函数就可以通过event来接收:


function eventHandler(e) {
  log('The time is: ' + e.detail);
}


当然,浏览器提供的事件相当多,今天分享的部分主要是比较常见的一些事件,以及工作上实际需要特別注意的部分。

其他的多数事件你都可以在 MDN 的 Event reference 找到。