JavaScript高级程序之13——事件

第13章 事件

1. 事件流

  • 事件流:描述页面接受事件的顺序
  • 事件冒泡流
    • 事件由目标元素接受,向上传播至document(部分浏览器会到window)
  • 事件捕获流
    • 事件由document对象(规范要求,但浏览器还是从window对象开始捕获)接收,向下传播搭配目标
  • DOM事件流的三个阶段
    • 捕获阶段不接受事件(规范要求)
    • 实际上主流浏览器都会在捕获阶段触发事件对象上的事件

在这里插入图片描述

2. 事件处理程序(事件侦听器)

  • 概念

    • 响应事件的函数就是事件处理程序
    • 事件处理程序名字以on开头
    • 为事件指定处理程序的方式:HTML事件、DOM0级事件、DOM2级事件
    • 事件处理程序代码执行时有权访问全局作用域中的任何代码
  • HTML事件处理程序

    • 使用HTML特性指定事件处理程序

    • <div onclick="alert('莫挨老子!')">点我</div>

    • 也可调用脚本函数

    • 可通过event变量直接访问事件对象

    • 可通过this访问目标元素(若使用箭头函数,则this指向window)

      /*
      <div οnclick="handler">点我</div>
      */
      
      function handler(e){
        console.log(this == e.currentTarget); // true
      }
      
    • 缺点

      • 时差问题:执行函数未解析前触发事件,会报错。解决方案是使用try-catch封装事件处理程序
      • 事件处理程序的作用域链在不同浏览器中可能导致不同结果
      • HTML与JS紧密耦合,更换事件处理程序HTML与JS均需要改动
  • DOM0级事件处理程序

    • 将函数赋值给事件处理程序属性
    • 优势:简单,可跨浏览器
    • 被认为是元素的方法,可通过this引用当前元素,并访问元素属性和方法
    • 删除事件处理程序:属性值设为null即可
    • 设置多次事件属性值,旧值会被新值覆盖
    let d = document.getElementById("ddd");
    d.onclick = function(){
      console.log(this.id); // "ddd"
    };
    d.onclick = null; 删除
    
  • DOM2级事件处理程序

    • 处理指定和删除事件处理程序的操作addEventListener()和removeEventListener()
    • 可用于所有DOM节点
    • 接受3个参数:
      • 事件名(不以“on”开头)
      • 处理函数(不要是匿名函数)
      • 是否捕获事件(true/false):默认是冒泡事件(考虑兼容性,不建议设置为true)
    • addEventListener()
      • 可以添加多个事件处理程序,按添加顺序依次触发执行
    • removeEventListener()
      • addEventListener()添加的事件只能用removeEventListener()移除
      • 传入参数必须一致,因此,匿名函数无法移除
    • 不建议捕获阶段注册事件
  • IE事件处理程序

    • attachEvent()和detachEvent()
      • 两个参数:事件名(on开头)、处理函数
      • 作用域区别:this指向window
      • 多个事件触发顺序与添加顺序相反
  • 跨浏览器的事件处理程序

    • 默认使用DOM0级事件
  • 小结

    • HTML事件会被DOM0级事件覆盖
    • DOM0级事件触发优先于DOM2级事件
    • DOM2级事件可以添加多次事件处理程序

3. 事件对象

  • DOM中的事件对象

    • DOM0与DOM2事件处理程序都会传入event对象(HTML事件也可传入event)
    • 所有事件都有的属性与方法
      • 事件处理程序内部this指向currentTarget(绑定事件的元素)的值
      • target为触发事件的元素
      • type属性可以用于一个函数处理多个事件(结合switch语句)
      • eventPhase属性确定事件流处于哪个阶段,1表示捕获、2表示处于目标、3表示冒泡
      • 只有cancelable为true时,才可取消默认行为
      • preventDefault():阻止事件默认行为(如链接的跳转)
      • stopPropagation():立即停止事件传播(冒泡或捕获)
        在这里插入图片描述
  • IE中的事件对象

    • DOM0级事件的event对象作为window的属性存在

    • HTML特性指定事件处理程序则可通过event变量访问事件对象

    • 使用attachEvent()时,event对象会作为参数传入事件处理函数

    • 属性与方法
      在这里插入图片描述

4. 事件类型

  • DOM3级事件分类

    • UI事件:load、unload、resize、scroll等
    • 焦点事件:blur、focus等
    • 鼠标与滚轮事件
    • 文本事件
    • 键盘事件
    • 合成事件
    • 变动事件
  • UI事件

    • load事件
      • 可以用在window、image、或iframe
      • 可以使用HTML特性、DOM0、DOM2三种方法指定事件处理程序
    • unload事件
      • 文档完全卸载后触发(前进或后退页面)
      • 可用于清除引用,以避免内存泄漏
    • resize事件
      • 窗口最大化最小化也会触发
      • 持续触发
    • scroll事件
      • 滚动时会重复触发
  • 焦点事件

    • focus与blur事件不冒泡
  • 鼠标事件

    • click:相继触发mousedown与mouseup才触发

    • dbclick:触发两次click

    • mousedown、mouseup

    • mouseenter/mouseleave

      • 不冒泡
      • 移到后代元素不触发
    • mouseout/mouseover:

      • 指针由一个元素上方移出/入另一个元素(可以是外部元素也可以是子元素
      • 会冒泡
    • mousemove:移动会重复触发

    • 鼠标事件包含以下属性

      • clientX/clientY:鼠标指针在视口的坐标
      • pageX/pageY:页面中的坐标(页面不滚动时与视口坐标相等)
      • screenX/screenY:屏幕坐标
      • shiftKey、ctrlKey、altKey、metaKey(win或cmd):布尔值,是否按下对应键
      • relatedTarget:相关元素(IE中使用的是fromElement/toElelment)对应mouseover和mouseout
      • button:鼠标按钮
        在这里插入图片描述
  • 滚轮事件

    • onscroll:处理的是对象内容(页面)滚动事件
    • onwheel:处理的是鼠标滑轮滚动事件,只要滚动滑轮就会触发,event对象有以下属性
      • deltaX/Y/Z属性:3的倍数,表示滚动方向与距离
  • 键盘与文本事件

    • keydown:按下任意键盘触发,按住不放持续触发

    • keyup:释放键盘时触发

      • keyCode:键码
      • charCode:始终为0
    • keypress:按下字符键盘触发,按住不放持续触发

      • charCode:字符编码(同keycode)
      • keycode:始终为0
      • 按shift键会改变charcode值
      • 会区分大小写
    • 其它共有属性

      • key:键盘字符串
      • location:键位置(0默认键盘,1左侧,2右侧,3小键盘,4移动设备键盘或虚拟键盘,5手柄)
        • 按下左右侧的 altcrtlshift分别为1、2
    • shift + +触发键盘事件顺序如下:
      在这里插入图片描述

    • textInput:对keypress的补充,在可编辑区域输入字符时触发

  • 复合事件

  • 变动事件

    • 删除节点(removeChild()、replaceChild())
      • DOMNodeRemoved:冒泡,事件目标为被删除节点
      • DOMNodeRemovedFromDocument:不冒泡,事件目标为被删除节点及其子节点(event不包含其它信息)
      • DomSubtreeModified::冒泡,事件目标为被删除节点的父节点
    • 插入节点(appendChild()、replaceChild()、insertBefore())
      • DOMNodeInserted:冒泡,事件目标为被插入节点
      • DOMNodeInsertedInDocument:不冒泡,事件目标为新插入的节点(event不包含其它信息)
      • DomSubtreeModified::冒泡,事件目标为新插入节点的父节点
  • HTML5事件

    • contextmenu事件

      • 鼠标右键调出上下文菜单
      • 先使用event.preventDefault()方法阻止默认右键菜单栏,然后自定义右键菜单
      /*
      <div 
      	id="menu"
      	style="position: absolute;
      		background:pink;
      		visibility: hidden;">
      	我是如影随形的小可爱!
      </div>
      */
      
      let menu = document.getElementById("menu");
      document.oncontextmenu= ()=>{
        event.preventDefault();
        menu.style.visibility = "visible";
      }
      document.onmousemove=()=>{
        	menu.style.top = event.clientY + "px";
          menu.style.left = event.clientX + "px";
      }
      document.onclick=()=>{
        menu.style.visibility = "hidden";
      }
      
    • beforeunload事件(window对象)

      • 浏览器卸载页面前触发,弹出提示框,控制权交给用户
      • 无法彻底取消该事件(相当于无法离开页面)

在这里插入图片描述

  • DOMContentLoaded事件

    • load事件:一切加载完毕时触发,可能由于资源过多而耗时
    • DOMContentLoaded事件是形成完整的DOM树就会触发
      • 不管image、js、css等文件及其他资源是否加载完毕
    • 可以更早的与页面交互
    • 目标(target)对象为document
  • hashchange事件(window对象)

    • event额外包含两个属性:oldURL和newURL(完整的URL)
    • AJAX应用中,利用hash值来保存状态或导航信息
  • 设备事件

  • 触摸与手势事件

5. 内存与性能

  • 事件委托
    • 事件处理程序过多时,利用事件冒泡来管理某一类型的所有事件
    • 适合委托的事件:click、mousedown、mouseup、keyup、keydown、keypress
  • 移除事件处理程序
    • 产生不用的事件处理程序的情况:
      • 从文档移除的带有事件处理程序的元素(使用innerHTML替换元素时)
      • 卸载页面(刷新、关闭)
    • 移除方法:将null赋值给事件处理程序

6. 模拟事件(DOM 3级事件)

  • 模拟DOM事件
    • 创建Event对象:e = document.createEvent(eventType)
      • 参数可选值:UIEvent | MouseEvent | KeyboardEvent |MutationEvent
    • 初始化:e.initxxx(options)
    • 触发事件:selectedElement.dispatchEvent(e)
  • 模拟IE中的事件:createEventObject()
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值