关于事件要了解的问题总结笔记

事件(event)

  • 事件就是 web 浏览器通知应用程序发生了什么事情。事件是可以被 javascript 侦测到的行为。
  • 事件类型(event type)是一个用来说明发生什么类型事件的字符串。由于事件类型只是一个字符串,因此实际上有时会称之为事件名字(event name)。
  • 事件目标(event target)是发生的事件或与之相关的对象。
  • 事件处理程序(event handler)或事件监听程序(event listener)是处理或响应事件的函数。应用程序通过指明事件类型和事件目标,在 web 浏览器中注册它们的事件处理程序函数。
  • 事件对象(event object)是与特定事件相关且包含有关该事件详细信息的对象。
  • 事件传播(event propagation)是浏览器决定哪个对象触发其事件处理函数的过程。

事件类型(event type)

  1. 传统事件类型
  2. 表单事件
- submit 事件:提交按钮(``)被点击。
- reset 事件:重置按钮(``)被点击。 
- focus 事件:元素获得焦点。
- blur 事件:元素失去焦点。
- change 事件:改变域的内容。
  1. window 事件
- load 事件:某个页面或图像被完成加载。
- unload 事件:用户退出页面。
- beforeunload:在即将离开当前页面(刷新或者关闭)是执行。
- error 事件:当加载文档或图像时发生某个错误。
- resize 事件:窗口或框架被调整尺寸。
- scroll 事件:元素滚动条滚动。
  1. 鼠标事件
- mousemove 事件:鼠标被移动或拖动鼠标。
- mouseout 事件:鼠标不再悬停到某个元素上。
- mousedown 事件:鼠标按下。
- mouseup 事件:鼠标释放。
- click 事件:单击鼠标按键。
- dblclick 事件:短时间连续两次单击(双击)鼠标按键。
  1. 键盘事件
- keydown 事件:某个键被按下。
- keyup 事件:某个键被松开。
- keypress 事件:某个键被按下或按住。
  1. DOM 事件
  2. HTML5 事件
    HTML5及相关标准定义了大量的新的 web 应用 api。
    广泛推广的HTML5特性之一是加入用于播放音频和视频的 元素。这些元素有着长长的事件列表,他们触发各种关于网络事件、数据缓冲状况和播放状态的通知。
    html5事件_1.png

    拖放事件:
    html5事件_2.png
  3. 触摸屏和移动设备事件
  4. 手势事件 gesture
- gesturestart 事件:手势生成。
- gesturechange 事件:手势过程。
- gestureend 事件:手势结束。
  1. 触摸事件 touch
- touchstart 事件:手指触摸屏幕。
- touchmove 事件:手指移动。
- touchend 事件:手指离开。
  1. 横竖屏切换 orientation
- orientationchange 事件:竖屏旋转到横屏模式。 
  window 对象的 orientation 属性能给出当前方位,其值是 0,90,180,-90。

注册事件处理程序

  1. 设置 javascript 对象属性为事件处理程序
    事件处理程序属性的名字由 “on” 后面跟着事件名组成:onclick、 onchange、 onload、 onmouseover 等。
window.onload = funciton () {
  var elt = document.getElementById("shipping_address");
  elt.onsubmit = function () {
    return validate(this);
  }
}
  1. 设置 HTML 标签属性为事件处理程序
    设置的文档元素事件处理程序属性(property)也能换成对应 HTML 标签的属性(attribute)。

  1. addEventListener()
    除 IE8 及之前版本外的所有浏览器都支持。
    addEventListener() 接收三个参数。第一个是要注册处理程序的事件类型(不包括 on );第二个参数是当指定类型的事件发生时应该调用的函数。最后一个参数是布尔值。通常情况下,会给这个参数传递 false。如果相反传递了 true,那么函数将注册为捕获事件处理程序,并在事件不同的调度阶段调用。
var b = document.getElementById("mybutton");
b.addEventListener("click", function() { alert("thanks!")}, false);
document.removeEventListener("mousemove", handleMouseMove, true);
  1. attachEvent
    IE9 之前的 IE 不支持 addEventListener() 和 removeEventListener()。
    IE5 及以后版本定义了类似的方法 attachEvent() 和 detachEvent()。
  • addEventListener()、 removeEventListener() 和 attachEvent()、 detachEvent() 区别
    • 因为 IE 事件模型不支持事件捕获,所以 attachEvent() 和 detachEvent() 要求只有两个参数:事件类型和处理程序函数。
    • IE 方法的第一个参数使用了带 “on” 前缀的事件处理程序属性名。而非没有前缀的事件类型。
    • attachEvent() 允许相同的事件处理函数注册多次。当特定的事件类型发生时,注册函数的调用次数和注册次数一样。
    • this的区别
      addEventLisener:事件处理程序会在当前对象的作用域运行,因此,事件处理程序的 this 就是当前对象。
      attachEvent:事件处理程序是在全局作用域下运行因此 this 就是 window 。
var b = document.getElementById("mybutton");
var handler = function () {
  alert("thanks");
};
if (b.addEventListener) {
  b.addEventListener("click", handler, false);
} else if (b.attachEvent) {
  b.attachEvent("onclick", handler);
}

移除事件的兼容写法:

var EventTools={
  removeEventListener:function (element,eventName,listener) {
    if(element.removeEventListener){
      element.removeEventListener(eventName,listener,false);
    }else if(element.detachEvent){
      element.detachEvent("on"+eventName,listener);
    }else{
      element["on"+eventName]=null;
    }
  }
};

事件传播

事件传播的三个阶段

  1. 捕获
  2. 目标:正在执行当前对象的事件处理程序。
  3. 冒泡
关于事件要了解的问题总结笔记_第1张图片
事件传播三个阶段.png

事件捕获和事件冒泡

  1. 事件冒泡


    关于事件要了解的问题总结笔记_第2张图片
    事件冒泡.png

    如果元素 A 嵌套在元素 B 中,那么 A 被点击不仅 A 的 onclick 事件会被触发,B 的 onclick 也会被触发。触发的顺序是“由内而外” 。

  • 取消事件冒泡:
  window.event.cancelBubble = true;//IE
  e.stopPropagation();
  • 如何阻止事件冒泡和默认事件?
//阻止浏览器的默认行为
window.event?window.event.returnValue = false : e.preventDefault();
//停止事件冒泡
window.event?window.event.cancelBubble = true : e.stopPropagation();

原生 JavaScript 中,return false; 只阻止默认行为,不阻止冒泡,jQuery 中的 return false; 既阻止默认行为,又阻止冒泡。

  1. 事件捕获


    关于事件要了解的问题总结笔记_第3张图片
    事件捕获.png

    和事件冒泡正好相反,逐级向下传播,触发的顺序是“由外而内”

其他

事件代理/委托的原理以及优缺点

  1. 原理:靠事件的冒泡机制来实现。让自己所触发的事件由他的父元素代替执行。
  2. 优点:可以大量节省内存占用,减少事件注册。可以实现当新增子对象时无需再次对其绑定事件,对于动态内容部分尤为合适。
  3. 缺点:事件代理的应用常用应该仅限上述需求下,如果把所有的事件都代理就可能出现事件误判,即本不应用触发事件的被绑上了事件(有人把页面里所有的时间都绑定到 document 用委托的,只是及其不智的做法)

实现事件代理,要求兼容浏览


// ============ 简单的事件委托
function delegateEvent(interfaceEle, selector, type, fn) {

    if(interfaceEle.addEventListener){
    interfaceEle.addEventListener(type, eventfn);
    }else{
    interfaceEle.attachEvent("on"+type, eventfn);
    }
     
    function eventfn(e){
    var e = e || window.event;    
    var target = e.target || e.srcElement;
    //如果目标元素与选择器匹配则执行函数
    if (matchSelector(target, selector)) {
            if(fn) {
                //将fn内部的this指向target(在此之前this都是指向的绑定事件的元素即interfaceEle)
                fn.call(target, e); 
            }
        }
    }
}
/**
 * only support #id, tagName, .className
 * and it's simple single, no combination
 */
//比较函数:判断事件的作用目标是否与选择器匹配;匹配则返回true
function matchSelector(ele, selector) {
    // 如果选择器为ID
    if (selector.charAt(0) === "#") {            
        return ele.id === selector.slice(1);   
    }
    //charAt(0),返回索引为0的字符
    //slice(a,b),从已有的数组或字符串返回从索引从a处开始,截取到索引b之前的子数组或子字符串;
    //如果选择器为Class
    if (selector.charAt(0) === ".") {
        return (" " + ele.className + " ").indexOf(" " + selector.slice(1) + " ") != -1;
    }
    // 如果选择器为tagName
    return ele.tagName.toLowerCase() === selector.toLowerCase();
}
//toLowerCase()将字符串转换成小写
//调用
var odiv = document.getElementById("oDiv");
delegateEvent(odiv,"a","click",function(){
    alert("1");
})

参考自:

javascript权威指南
1.事件委托的原理以及优缺点 2. 手写原生js实现事件代理,并要求兼容浏览器

你可能感兴趣的:(关于事件要了解的问题总结笔记)