DOM事件的基础知识

什么是事件?什么是事件绑定?

1.事件就是一件事情或者一个行为(对于元素来说,它的很多事件都是天生自带的),只要我们去操作这个元素,就会触发这些行为
2.事件绑定:给元素天生自带的事件行为绑定方法,当事件触发,会把对应的方法执行
常见的事件行为

  1. [鼠标事件]
  2. * click 点击(移动端click被识别为单击,且在移动端有300毫秒的延迟)
  3. * dblclick 双击
  4. * mousedown 鼠标按下,鼠标左右键都起作用,按下即触发,click是按下抬起才会触发,而且是先把downup触发,才会触发click
  5. * mouseup 鼠标抬起
  6. * mousemove 鼠标移动
  7. * mouseover 鼠标滑过
  8. * mouseout 鼠标滑出
  9. * mouseenter 鼠标进入
  10. * mouseleave 鼠标离开
  11. * mousewhell 鼠标滚轮滚动
  12. [键盘事件]
  13. * keydown 按下某个键
  14. * keyup 抬起某个键
  15. * keypress Shift/Fn/CapsLock键以外,其它键按住(连续触发)keydown返回的是键盘码,keypress返回的是ASCII
  16. * input PC端有实物物理键盘,可以监听到键盘的按下和抬起,但是移动端是虚拟键盘,因此keydownkeyup在大部分手机上都没有,使用inpu事件统一替代他们(内容改变事件)
  17. [移动端手指事件]
  18. * 单手指事件模型 Touch
  19. * touchstart 手指按下
  20. * touchmove 手指移动
  21. * touchend 手指松开
  22. * touchcancel 操作取消(一般应用于非正常状态下操作结束,即意外情况导致手指操作取消
  23. * 多手指事件模型 Gesture
  24. * gesturestart 手指按下
  25. * gesturechange / gestureupdate
  26. * gestureend 手指离开
  27. * gesturecancel
  28. * [表单元素常用事件]
  29. * focus 获取焦点
  30. * blur 失去焦点
  31. * change 内容改变
  32. * [音视频常用事件]
  33. * canplay 可以播放(资源没有加载完,播放中可能会卡顿)
  34. * canplaythrough 可以播放(资源已经加载完,播放中不会卡顿)
  35. * play 开始播放
  36. * playing 播放中
  37. * pause 暂停播放
  38. * [其它常用事件]
  39. * load 资源加载完
  40. * unload 资源卸载
  41. * beforeunload 当前页面关闭之前
  42. * error 资源加载失败
  43. * scroll 滚动事件
  44. * resize 大小改变事件
  45. window.onresize=function(){} 当浏览器窗口大小发生改变,
  46. 会触发这个事件,执行对应的事情
  47. * readystatechange AJAX请求状态改变事件
  48. * contextmenu 鼠标右键触发
  49. * ......
  50. * https://developer.mozilla.org/zh-CN/docs/Web/Events
  51. * 或者查看元素的属性(属性中onxxx就是元素拥有的事件行为)
  52. */

DOM0事件绑定 VS DOM2事件绑定

  • 底层机制原理
  • 同一个事件绑定方法数量
  • 触发先后顺序
  • 支持事件类型

    [DOM0级事件]

    [element].onxxx=function(){}

    DOM0级事件绑定的原理:

    1. ** 给元素的私有属性赋值,当事件触发,浏览器会帮我们把赋的值执行,但是这样也导致‘只能给当前元素某一个事件行为绑定一个方法’**
  1. box.onclick = function () {
  2. console.log('哈哈哈~~');
  3. }
  4. box.onclick = function () {
  5. console.log('呵呵呵~~');//SyntaxError: Unexpected end of input
  6. }
  7. }
  8. //只能绑一个,第二个就会报错
  9. box.onclick=function(){
  10. console.log('呵呵呵····');
  11. //移出事件绑定:DOM0直接赋值为null
  12. box.onclick=null;
  13. }

[DOM2级事件]

  1. [element].addEventListener('xxx',function(){},false)<br /> [element].attachEvent('onxxx',fuunction(){}); [ie6-8]

DOM2事件绑定原理

** 基于原型链查找机制,找到EventTarget.prototype上的方法并执行,此方法执行,会把给当前元素
某一个事件行为绑定的所有方法,存放到浏览器默认的事件池中(绑定几个方法,会向事件池存储几个),当
事件行为触发,会把事件池中存储的对应方法,依次按照顺序执行“给当前元素某一个事件行为绑定多个不同
方法”**

  1. box.addEventListener('click'function(){
  2. console.log('哈哈哈~');
  3. },false);
  4. box.addEventListener('click',funtion(){
  5. console.log('呵呵呵~~')
  6. },false);

注意

DOM2事件绑定的时候,采用实名函数
目的:利于基于实名函数移出事件绑定

  1. function fn(){
  2. console.log('哈哈哈~~');
  3. //移出事件绑定:从事件池移除,所以需要指定事件类型,方法等信息(要和绑定的时候一样才可以移除)
  4. box.removeEventListener('click',fn,false)
  5. }
  6. box.addEventListener('click',fn,false);
  7. //基于addEventListener向事件池增加方法,存在去重的机制(同一个元素,同一个事件类型,在事件
  8. 池中只能存储一边此方法,不能重复存储),因此方法,函数,同步异步至少有一个不一样。
  9. box.addEventListener('click',fn1,false);
  10. box.addEventListener('mouseover',fn1,false);
  11. function fn1(){
  12. console.log(1);
  13. }
  14. function fn2(){ console.log(2); }
  15. function fn3(){ console.log(3); }
  16. box.addEventListener('click', fn2, false);
  17. box.addEventListener('click', fn3, false);
  18. box.addEventListener('click', fn1, false);


DOM0和DOM2可以混用,执行顺序以绑定顺序为主

  1. box.addEventListener('click',function(){
  2. console.log('哔咔哔咔~~');
  3. });
  4. box.onclick = function () {
  5. console.log('哇咔咔~~');
  6. }
  7. box.addEventListener('click', function () {
  8. console.log('call~~');
  9. });

DOM0中能做事件绑定的事件行为,DOM2都支持;DOM2中的一些事件,DOM0不一定能处理绑定,例如reansitionend,DOMContentLoaded..

  1. box.ontransitionend = function () {
  2. console.log('哇咔咔~~');
  3. }
  4. box.addEventListener('transitionend', function () {
  5. console.log('哇咔咔~~');
  6. });
  1. window.addEventListener('load',function(){
  2. //所有资源都加载完成触发
  3. console.log(' 加载');
  4. });
  5. window.addEventListener('DOMContentLoaded',function(){
  6. //只要DOM结构加载完成就会触发
  7. console.log('DOMContentLoaded');
  8. })
  9. //$(document).ready(function(){})
  10. $(function(){
  11. //jq中的此处理(dom结构加载完触发),采用的就是DOMContentLoaded事件,并且依托dom2事件绑定处理
  12. 所以同一个页面,此操作可以被使用
  13. })
  14. $(function(){})//jq中的事件绑定采用的是dom2事件绑定。on/one/off...

window.onload&&$(document).ready()

  1. $(document).ready()采用的是dom2事件绑定,监听的是DOMContentLoaded事件,所以只要dom结构加载完

    就会被触发执行,而且同一个页面中可以使用多次(绑定不同的方法,因为基于事件池绑定机制完成的)

  2. window.onload必须等待所有的资源加载完成才会被触发执行,采用dom0事件绑定,同一个页面只能绑定一次

    ,(一个方法),想绑定多个也需要借助dom2绑定方式-》window.addEventListener(‘load’,function(){})

    目的:
    给当前元素的某一个事件绑定方法(不论是基于dom0还是dom2),都是为了触发元素的相关行为的时候
    ,能做点事情(就是将绑定的方法执行):‘不仅把方法执行了,而且浏览器还会给方法传递一个实参信
    息值’=》值是事件对象

  1. box.onclick=function(ev){
  2. //定义一个形参ev用来接收方法执行的时候,浏览器传递的信息值(事件对象:MouseEvent鼠标事件对象,
  3. KeyboardEvent键盘事件对象、Event普通事件对象...))
  4. ///=>事件对象中记录了很多属性名和属性值,这些信息中包含了当前操作的基础信息,例如:
  5. 鼠标点击位置的X/Y轴坐标,鼠标点击的是谁(事件源)等信息
  6. }