zoukankan      html  css  js  c++  java
  • 谈谈JavaScript事件

    众所周知,web前端包含三个基本技术:html、css和javascript。三者融合,才让网页变得精彩纷呈!如今,web上的操作越来越趋于复杂,JavaScript事件在网页中也遍地开花,有时候也是遍地生Bug。真正理解了JavaScript的事件模型,才能在实际开发中佛挡杀佛,bug挡杀bug。

    前言

    这是我自己对JavaScript事件模型的理解,并且参考了网络上的各家之言。由于本人才疏学浅,难免有错误之处,还望指正。
    在工作学习中,你或许不知道见过多少事件了。那么,到底什么是JavaScript事件呢?我们先来运行一段代码:

    var out = [];
    for ( var i in window) {
      if ( /^on/.test(i)) { out[out.length] = i; }
    }
    console.log(out);
    

    是不是看到了如下一大串东西(我是在chrome中运行的)?

    ["onautocompleteerror", "onautocomplete", "ondeviceorientation", "ondevicemotion", "onunload", "onstorage", "onpopstate", "onpageshow", "onpagehide", "ononline", "onoffline", "onmessage", "onlanguagechange", "onhashchange", "onbeforeunload", "onwaiting", "onvolumechange", "ontoggle", "ontimeupdate", "onsuspend", "onsubmit", "onstalled", "onshow", "onselect", "onseeking", "onseeked", "onscroll", "onresize", "onreset", "onratechange", "onprogress", "onplaying", "onplay", "onpause", "onmousewheel", "onmouseup", "onmouseover", "onmouseout", "onmousemove", "onmouseleave", "onmouseenter", "onmousedown", "onloadstart", "onloadedmetadata", "onloadeddata", "onload", "onkeyup", "onkeypress", "onkeydown", "oninvalid", "oninput", "onfocus", "onerror", "onended", "onemptied", "ondurationchange", "ondrop", "ondragstart", "ondragover", "ondragleave", "ondragenter", "ondragend", "ondrag", "ondblclick", "oncuechange", "oncontextmenu", "onclose", "onclick", "onchange", "oncanplaythrough", "oncanplay", "oncancel", "onblur", "onabort", "onwheel", "onwebkittransitionend", "onwebkitanimationstart", "onwebkitanimationiteration", "onwebkitanimationend", "ontransitionend", "onsearch"]
    

    没错,这些都是JavaScript事件!但也不仅仅是这些。

    DOM1级事件处理

    为什么不是DOM0级事件,以为DOM0级规范压根就没有形成。DOM1级事件处理是当今所有浏览器都支持的事件处理,不存在任何兼容性问题,。DOM0事件处理的规则:每个DOM元素都有自己的事件处理属性,该属性可以赋值一个函数,例如:

    var btnDOM = document.getElementById("btn");
    btnDOM.onclick = function(){
        alert("you click me!");            
    }
    

    DOM0级事件处理的事件属性都是采用“on+事件名称”的方式定义,整个属性都是小写字母。DOM元素在JavaScript代码是作为对象处理的,例如:

    btnDOM.onclick = null;
    

    那么按钮的点击事件被取消了。

    DOM1级事件可以被覆盖,例如:

    btnDOM.onclick = function(){
        alert(" you click me!");            
    }
    btnDOM.onclick = function(){
        alert("also click me!");            
    }
    

    后面一个函数会将第一个函数覆盖。

    DOM2级事件处理(IE9及其以上支持)

    首先说说事件流。事件流描述的是从页面中接收事件的顺序。早期的IE事件流叫做事件冒泡,Netscape团队提出的是事件捕获。
    如下图:

    event-old

    而现在常用的DOM2级事件流(也称标准事件模型)是包括了三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段。
    如下图:

    event-standard

    DOM2事件处理里添加事件使用的是addEventListener,它接收三个参数,第三个参数默认为false,表示在冒泡阶段调用事件处理程序。如果设为true,则表示在事件捕获阶段处理程序。

    var btnDOM = document.getElementById("btn"); 
    btnDOM.addEventListener("click",function(){ 
        alert("Click Me!");
    },false);
    var ftn = function(){ 
        alert("Click Me,too!");
    };
    btnDOM.addEventListener("click",ftn,false);
    

    删除事件使用removeEventListener,其中参数要和定义事件的参数一致,第三个参数不传,默认是删除冒泡事件,因为第三个参数不传默认都是false,例如下面的代码是不能成功删除事件的:

    btnDOM.addEventListener("click",ftn,true);
    btnDOM.removeEventListener("click",ftn);
    

    事件冒泡有时候并不是我们所想要的。所以我们需要来阻止事件冒泡,标准方法是:

    event.stopPropagation();
    

    IE 可能会使用到下面这个方法:

    event.cancelBubble = true;
    

    事件对象event里面存在target和currentTarget。我们知道事件其实是观察者模式。target其实是事件的发布者(event dispatcher),currentTarget是事件的处理者(event processor)。

    说明:

    1. target发生在事件流的目标阶段,而currentTarget发生在事件流的整个阶段(捕获、目标和冒泡阶段)
    2. 只有当事件流处于目标阶段的时候二者才相同
    3. 而当事件流处于捕获和冒泡阶段时,target指向被点击的对象,而currentTarget指向当前事件活动的对象。

    知道了这个原理,我们便可以理解事件委托(也称事件代理)的实现原理了。

    DOM3及DOM4事件处理

    这是未来的事情了。

  • 相关阅读:
    网络编程【二】socket(套接字)初识
    网络编程【一】操作系统的发展史
    面向对象【十三】类的魔术方法
    面向对象【十二】包装和授权
    面向对象【十一】类内置的attr属性
    面向对象【十】反射
    openwrt 编译错误
    修改openwrt 终端登录欢迎界面
    openwrt quilt 使用
    openwrt luci 入门介绍
  • 原文地址:https://www.cnblogs.com/myqianlan/p/4196005.html
Copyright © 2011-2022 走看看