JavaScript(四)

基于《JavaScript高级程序设计》


事件

  • 事件捕获
  • 目标阶段
  • 事件冒泡
  1. 事件处理程序:响应某个事件的函数,均以”on”开头

    eg:

    1
    2
    3
    4
    5
    <form method="POST">
    <input type="text" name="username" value="">
    <!-- 作用域包含父元素入口 -->
    <input type="button" value="Echo Username" onclick="alert(username.value)">
    </form>

    像这样创建一个封装着元素属性值的函数,有一个局部变量event事件对象,在函数内部其this值等于事件的目标元素。

    i. DOM 0级事件处理程序

    先获取元素的引用,再为其指定事件处理程序

    eg:

    1
    2
    3
    4
    5
    6
    var btn = document.getElementById("myBtn");
    // 方括号语法也行 btn["onclick"] = function(){};
    btn.onclick = function(){
    alert("Clicked");
    // alert(this.id); // "myBtn" 在该元素的作用域下
    }

    ii. DOM 2级事件处理程序

    addEventListener() / removeEventListener() 接收三个参数:

    • 处理的事件名
    • 事件处理程序的函数
    • 布尔值,true表在捕获阶段调用,false表在冒泡阶段调用

    也需要先引用指定元素。另外注意removeEventListener()不能传递匿名函数,因为会认为两者不相等导致清除事件失败,所以必须得先用个变量保存(函数表达式)。

    iii. 跨浏览器事件处理程序

    利用EventUtil对象的addHandler() / removeHandler()方法,接收三个参数:操作的元素,事件名称,事件处理程序函数

  2. 事件对象:触发DOM上某个事件都会产生一个事件对象event,该对象包含着所有与事件有关的信息。它也一定会被传入到事件处理程序中(隐式的)

    所有事件包含下列属性:

    在事件处理程序内部,对象this始终等于currentTarget值,target为事件的目标,所以如果事件处理程序直接指定给目标元素的话,三个值都相等,但是如果事件处理程序为目标元素的父节点,则不相等。

    方法:

    • event.preventDefault() 阻止特定事件(cancelable设置为true)的默认行为,比如点击链接跳转URL的默认行为

    • event.stopPropagation() 立即停止事件在DOM层次中的传播,比如在body和body中的button都定义了不同的click事件,如果不停止传播,那么点击button将会触发两个事件处理程序。

  3. 事件类型

    • UI事件:用户与界面上的元素交互时触发

      • load / unload

      设置\<script\>元素的load事件:

      1
      2
      3
      4
      5
      6
      7
      8
      EventUtil.addHandler(window, "load", function{
      var script = document.createElement("script");
      EventUtil.addHandler(script, "load", function(event){
      alert("Loaded.")
      });
      script.src = "example.js";
      document.body.appendChild(script);
      });
      • abort
      • error
      • select
      • resize
      • scroll
    • 焦点事件:页面元素获得或者失去焦点时触发,与document.hasFocus()document.activeElement()配合

      • blur 失去焦点时触发
      • focus 获得焦点时触发,两者都不会冒泡
      • focusin/focusout 字面意思,会冒泡
    • 鼠标与滚轮事件

      鼠标事件:

      • click / dbclick
      • mousedown / mouseup
      • mouseenter / mouseleave 不冒泡
      • mousemove
      • mouseover / mouseout

      event两个属性clientX / clientY为事件发生时在视口的水平和垂直坐标(自左自上)

      pageX / pageY 为在页面中的位置

      screenX / screenY 为在电脑屏幕中的位置

      event.shiftKey / ctrlKey / altKey / metaKey 为修改键属性,都是bool值,按下则为true。

      对于mouseover / mouseout,存在相关元素,event.relatedTarget提供了其信息

      滚轮事件:

      • mousewheel, event.wheelDelta属性与之对应
    • 键盘与文本事件

      • keydown / keyup
      • keypress 按下字符键,包括Esc

      event.keyCode属性包含一个代码与键对应

      DOM3引入的新事件 textInput,当用户在可编辑区域中输入实际字符时,就会触发这个事件。event.data值为用户输入的值。

    • 复合事件:处理IME的输入序列

    • 变动事件:DOM中的某一部分发生变化时触发

    • hashchange事件:URL的参数列表发生变化时触发,event.oldURL/newURL

    • 设备事件

      • orientationchange(safari) / MozOrientation(Firefox) / deviceorientation 通过三个轴进行变化的检测

      • devicemotion : 设备移动属性,包括加速度值等

    • 触摸手势事件

  4. 内存和性能

    • 事件委托:利用事件冒泡,通过对DOM树尽量高的元素指定一个事件处理程序来达到管理一类型的所有事件的目的。

    • onload添加的东西都需要通过onunload清除,否则就会滞留在内存中,导致内存没有被释放,从而造成性能下降。

  5. 模拟事件:由js来模拟触发特定的事件

    • DOM中的事件模拟,document.createEvent()创建event对象,接受一个参数为要创建的事件类型的字符串:
      • UIEvents / MouseEvents / MutationEvents / HTMLEvents (注意DOM3中这些字符串全为单数形式)
      • dispatchEvent()传入一个参数为event对象,触发事件
      • 初始化这些对象,对应都有一个initxxx()方法,接收很多参数。