xinglee23/Blogs

浅谈事件

Opened this issue · 0 comments

浅谈事件

  • 事件:就是文档或浏览器窗口中发生的一些特定的交互瞬间。(Javascript与HTMl之间的交互通过事件实现。)
  • 事件流:描述的是从页面中接收事件的顺序。
  • 事件三个阶段:捕获、目标、冒泡

DOM0 级事件

  • 方法指定的事件处理程序被认为是元素的方法。

DOM2 级事件:

  • DOM2级事件定义了两个方法,addEventListener()和removeEventListener()分别用于指定和删除事件。所有DOM节点中都包含这两个方法,并且它们都接受3 个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。

  • currentTarget: 其事件处理程序当前正在处理的那个元素

  • target: 事件的目标 —IE为srcElement

  • preventDefault(): 阻止特定事件的默认行为(只有当cancelable属性为true的事件才可使用)—IE为
    returnValue

  • stopPropagation(): 停止事件的传播 —IE为cancelBubble

addEventListener()示例:
var btn = document.getElementById("myBtn");
btn.addEventListener("click", function(){
alert(this.id);
}, false);
btn.addEventListener("click", function(){
alert("Hello world!");
}, false);
removeEventListener()示例:
var btn = document.getElementById("myBtn");
btn.addEventListener("click", function(){
alert(this.id);
}, false);
btn.addEventListener("click", function(){
alert("Hello world!");
}, false);
  • IE事件处理程序

  • attchEvent与detachEvent

  • 事件代理

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Document</title>
  <style>
    #content {
      position: absolute;
      top: 50%;
      height: 240px;
      margin-top: -120px; /* negative half of the height */
}
  </style>
</head>
<body>
  <div class="content"> Content goes here</div>  
  <ul id="list">
      <li id="item1">item1</li>
      <li id="item2">item2</li>
      <li id="item3">item3</li>
      <li id="item4">item4</li>
    </ul>
  <script>
   // 传统实现方式
    window.onload = function() {
      var ulNode = document.getElementById('list')
      var liNode = ulNode.childNodes || ulNode.children
      for(var i = 0; i < liNode.length; i++) {
        liNode[i].addEventListener('click', function(e) {
          alert(e.target.innerHTML)
        }, false)
      }
    }
   // 事件代理实现
    window.onload = function() {
      var ulNode = document.getElementById("list")
      ulNode.addEventListener('click', function(e) {
        if(e.target && e.target.nodeName.toUpperCase() == 'LI') {
          alert(e.target.innerHTML)
        }
      }, false)
    }
  </script>
</body>
</html>

兼容浏览器事件的写法

var EventUtil = {
  // 添加事件
  addHandler: function (element, type, handler) {
    if (element.addEventListener) {
      element.addEventListener(type, handler, false)
    // ie浏览器的事件写法
    } else if (element.attachEvent) {
      element.attachEvent("on" + type, handler)
    } else {
     // ie浏览器的事件写法
      element["on" + type] = handler
    }
  },
  // 使用事件默认会有event方法,ie浏览器event等于window.event
  getEvent: function(event) {
    return event ? event : window.event
  },
  // 获取浏览器目标事件
  getTarget: function(event) {
    return event.target || event.srcElement
  },
  // 阻止特定事件的默认行为
  preventDefault: function(event) {
    if(event.preventDefault) {
      event.preventDefault()
    } else {
      event.returnvalue = false
    }
  },
  // 停止事件的传播 
  stopPropagation: function() {
    if(event.stopPropagation) {
      event.stopPropagation()
    } else {
      event.cancelBubble = true
    }
  },
  // 删除事件
  removeHandler: function(element, type, handler) {
    if (element.removeEventListener) {
      element.removeEventListener(type, handler, false)
    } else if (element.detachEvent) {
      element.detachEvent("on" + type, handler)
    } else {
      element["on" + type] = null
    }
  }
}

事件委托

  • 过多的使用事件,会导致性能问题。其中一个解决方案就是事件委托
  • 事件委托:利用了事件冒泡,只指定�一个事件�处理程序,就可以管理某一类型的所有事件。
    🌰如下
  <ul id="myLinks">
    <li id="goSomewhere">Go somewhere</li>
    <li id="doSomething">Do something</li>
    <li id="sayHi">Say hi</li>    
  </ul>
  var list = document.getElementById("myLinks")
  EventUtil.addhandler(list, "click", funtion(event) {
    event = EventUtil.getEvent(event)
    var target = EventUtil.getTarget(event)

    switch(target.id) {
      case "doSomething":
        document.title = "I changed the document`s title"
        break
      case "goSomewhere":
        location.href = "www.efw.com"
        break
      case "sayHi":
        alert("hello")
        break
    }
  })