• JS学习笔记6_事件


    摘抄自:https://www.cnblogs.com/ayqy/p/4418033.html

    1.事件冒泡

    由内而外的事件传播(从屏幕里飞出来一支箭的感觉)

    2.事件捕获

    由表及里的事件传播(力透纸背的感觉)

    3.DOM事件流(DOM2级)

    事件捕获阶段 -> 处于目标阶段 -> 事件冒泡阶段(拿根针从屏幕扎进去,缝衣服的感觉)

    事件捕获是从DOM树根到叶子的事件传播,所以可以在靠近根的位置捕获(event.stopPropagation)事件,让叶子收不到事件信号

    事件冒泡是从叶子到根的原路返回过程,所以可以在靠近根的位置集中处理(event.target)叶子的事件,也就是所谓的事件委托,集中处理可以避免给多个叶子绑定事件处理器,拉低响应速度

    处于目标阶段只是规范要求,浏览器没怎么支持

    注意:[IE9+]支持事件捕获,事件冒泡是全浏览器支持

    4.添加事件处理器的几种方式

    1. HTML:on事件名 = strCode事件处理函数可直接访问的属性 = 全局属性 + 元素所在form中的属性 + 元素本身的属性

      自动的作用域扩展方式相当于:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      function(){
        with(document){//全局属性
          with(this.form){//表单属性
            with(this){
              //本身属性
            }
          }
        }
      }

      事件处理函数可以直接访问这么多属性,所以,可以这样做:

      1
      2
      3
      4
      <form method="post">
        <input type="text" name="user_name" value="">
        <input type="button" value="获取用户名" onclick="alert(user_name.value)">
      </form>
    2. DOM0级:elem.on事件名 = functionName/null;

      以这种方式添加的事件处理器在冒泡阶段执行,可直接访问的属性 = 全局属性 + 元素本身的属性

    3. DOM2级:(现代浏览器支持的)elem.add/removeEventListener(事件名, functionName, false/true);

      false表示在事件冒泡阶段添加,true表示在事件捕获阶段添加。可直接访问的属性同上

    4. [IE8-]:elem.attach/detachEvent(on事件名(on不能丢了), functionName);

      可直接访问的属性只有全局属性,而且对同一事件添加的多个处理器中,最后添加的最先执行,与DOM2级标准相反

    P.S.[IE8-]只支持事件冒泡,所以没有第三个参数,默认(也只能是)在事件冒泡阶段添加

    5.事件对象有什么用?

    1
    2
    3
    4
    5
    6
    btn.onclick = function(event){
      //event.target;获取事件源
      //event.preventDefault();取消默认行为,比如链接的跳转行为
      //event.stopPropagation();阻断事件传播
      //还有一些不常用的
    }

    注意:上面代码并不是全浏览器兼容的,事件对象的属性也不完整,更多信息请查看JS原生事件处理(跨浏览器)

    6.事件分类

    1. UI事件

    2. 焦点事件

    3. 鼠标事件

    4. 滚轮事件

    5. 文本事件

    6. 键盘事件

    7. 合成事件(用IME输入)

    8. 变动事件(DOM结构更新)

    9. HTML5事件

    10. 设备事件(特定设备,比如游戏机)

    11. 触摸与手势事件

    7.事件委托

    利用事件冒泡来减少事件处理器,以提升性能。甚至可以给document对象添加事件处理器,以求更短的交互准备时间(页面元素与事件处理器建立连接需要时间)

    事件委托的优点

    1. 设置事件处理器需要时间更少,因为DOM访问次数变少了

    2. 占用内存空间更少,因为事件处理器变少了

    3. 交互准备时间变短了,因为页面元素与事件处理器之间需要建立的连接变少了

    4. 页面响应速度变快了,因为页面元素与事件处理器之间建立的连接变少了

    8.移除事件处理器的注意事项

    在目标元素被从DOM树中删除前应该手动移除与之绑定的事件处理器,避免失效的事件处理器占用内存

    在页面unload之前,最好手动移除页面中的所有事件处理器,因为[IE8-]在unload页面时,事件处理器会滞留在内存中。可以在unload事件处理器中移除

    移除事件处理器的实质是断开页面元素与事件处理器之间的连接

    9.模拟事件的方式(即代码触发指定事件)

    1. 创建event对象

    2. 初始化event对象的各项属性

    3. 触发事件

    注意:[IE8-]的实现与DOM规范不同;DOM3级才能完美模拟键盘事件

    10.常识及性能优化策略

    1. 只有在需要拦截别的事件时才把事件处理器添加在捕获阶段,因为[IE8-]不支持事件捕获

    2. 对于动态创建的img元素,只要设置了src属性就会开始下载相关内容,而不是在新元素被插入DOM树后才开始

    3. 对于动态创建的script元素,只有插入DOM树后才会开始下载

    4. 对于动态创建的link元素(用来加载外部样式),只有插入到head部分才能保证浏览器表现一致,而且外部样式默认是异步加载

    5. 用in操作符来检测事件支持,例如:

      1
      2
      3
      if('onload' in elem){
        //do sth
      }
    6. hover, mouseover, mouseout, mouseenter, mouseleave的区别是什么?

      • hover是CSS伪类,鼠标进入并处于目标元素中时触发;
      • mouseover是鼠标事件,鼠标进入目标元素时触发,得到了浏览器广泛支持。相当于mouseenter,但nouseenter没有得到完全支持;
      • mouseout与mouseover相反,mouseleave与mouseenter相反,后者没有得到完全支持;
      • 本机测试:FF和IE全支持,Chrome不支持enter/leave。
    7. 事件委托是最重要的优化策略,当然,委托也不是完美的,委托会导致逻辑粘连,比如极端的情况,给document对象添加一个事件处理器就够了,但那将是一个很大只的函数。。。所以,应该在合适的地方尽量用委托

    8. 适时移除过期的时间处理器可以减少内存占用,这是空间方面的优化策略


  • 相关阅读:
    MySQL锁之三:MySQL的共享锁与排它锁编码演示
    服务链路追踪(Spring Cloud Sleuth)
    服务网关zuul之四:zuul网关配置
    hdu 1505 City Game (hdu1506加强版)
    PHP设计模式——訪问者模式
    极客互联网电视不是噱头,用户体验成创维G7200核心竞争力
    深入理解JavaScript系列(23):JavaScript与DOM(上)——也适用于新手
    使用php分页类实现简单分类
    管理之路(四)
    poj 2485 Highways (最小生成树)
  • 原文地址:https://www.cnblogs.com/smile-fanyin/p/14647325.html
Copyright © 2020-2023  润新知