Javascript事件小结

本篇文章主要讲解Javascript的事件,如下:

  • 事件流
  • 如何注册和删除事件
  • 跨浏览器的事件处理程序和事件对象
  • jquery触发事件的几种方式

事件是什么?

JavaScript与HTML之间的交互是通过事件实现的。
事件,就是文档或浏览器窗口中发生的一些特定交互瞬间,可以使用侦听器(或处理程序)来预订事件,以使事件发生时执行相应的代码。

事件流是什么?

事件流描述的是从页面中接收事件的顺序。
目前IE的事件流是事件冒泡流,Netscape的事件流是事件捕获流。
1、事件冒泡
事件冒泡,即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点。
比如:
···
<body>
<div onclick="handleClick()">Click</div>
</body>
···
点击div时,click事件首先在div元素上发生,然后沿DOM树向上传播,在每一级节点上都会发生,直至传播到document对象。传播顺序为:
(1)<div>
(2) <body>
(3) <html>
(4) document
所有现代浏览器都支持事件冒泡,IE9、Firefox、Chrome和Safari将事件一直冒泡到window对象。(IE5.5及更早版本中的事件冒泡会跳过<html>元素,从<body>直接跳到document)
2、事件捕获
事件捕获,是不太具体的节点更早接收到事件,最具体的节点最后接收到事件。事件捕获的用意在于在事件到达预定目标之前捕获它。
以上面的click事件为例,document对象首先接收到cick事件,然后事件沿DOM树依次向下,一直传播到事件的实际目标,即<div>元素。
事件捕获的传播顺序为:
(1) document
(2) <html>
(3) <body>
(4) <div>
目前,IE9、Firefox、Chrome和Safari也支持事件捕获,不过都是从window对象开始捕获事件。
总结:IE8只支持事件冒泡,IE9、Firefox、Chrome和Safari既支持事件冒泡也支持事件捕获。

如何添加事件处理程序(注册事件)

1、HTML事件处理程序
元素支持的每种事件,都可以用一个与相应事件处理程序同名的HTML特性指定。这个特定的值应该是能够执行的JavaScript代码。
如下:
通过给按钮指定onclick特性绑定了click事件,当点击按钮时就会执行handleClick函数。其中this为事件的目标元素,this.value就是input的value值。

  <body>
    <input type="button" value="click me" onclick="handleClick(this)">Click</div>
  </body>
  <script>
    function handleClick(){
      console.log(this.value); //click me
    }
  </script>

这种注册事件的方式使HTML与JavaScript代码紧密耦合,如果要更换事件处理程序,既需要修改HTML又需要修改JavaScript,很麻烦。
兼容性:IE8+、chrome、firefox、opera、safari
2、DOM0级事件处理程序
就是通过JavaScript注册事件,将一个函数赋值给一个事件处理程序属性,每个元素都有自己的事件处理程序属性,比如onclick,如下:
首先取得要操作的元素对象的引用,然后给它指定事件处理程序,其中this为当前元素

  <body>
    <input id="btn" type="button" value="click me">Click</div>
  </body>
  <script>
    var btn = document.getElementById('btn');
    //绑定事件
    btn.onclick = handleClick(){
      console.log(this.value); //click me
    }
  </script>
  //将事件处理程序属性值设置为null,即删除事件的绑定
  btn.onclick = null; 
//

兼容性:IE8+、chrome、firefox、opera、safari
3、DOM2级事件处理程序
就是使用addEventListener()注册事件,removeEventListener()删除事件addEventListener和removeEventListener都接受三个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值(如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序)
注意:

  • 用addEventListener注册事件,可以为一个元素同时添加多个事件处理程序,并且会按照他们的添加顺序触发
  • 用addEventListener注册事件只能用removeEventListener移除,并且移除时传入的参数必须与注册时相同
  <body>
    <input id="btn" type="button" value="click me">Click</div>
  </body>
  <script>
    var btn = document.getElementById('btn');
    //下面代码移除事件时看似传入的参数一样,其实第二个参数是完全不同的两个函数
    btn.addEventListener("click", function(){}, false); //添加事件处理程序
    btn.removeEventListener("click", function(){}, false); //移除事件处理程序

   //正确写法如下:
    var handler1 = function() {
        console.log(this.value);
    };
   var handler2 = function(){}
    btn.addEventListener("click", handler1, false); //添加事件处理程序handler1
    btn.addEventListener("click", handler2, false); //添加事件处理程序handler2
    btn.removeEventListener("click", handler1, false); //移除事件处理程序handler1
    btn.removeEventListener("click", handler2, false); //移除事件处理程序handle2
</script>

兼容性:IE9+、chrome、firefox、opera、safari
4、IE事件处理程序
就是attachEvent()和detachEvent()来注册事件和删除事件
attachEvent()和detachEvent()接受两个参数:事件处理程序名称和事件处理程序函数。
由于IE8只支持事件冒泡,所以通过attachEvent()注册事件会被添加到冒泡阶段。
注意:

  • attachEvent()的第一个参数是"onclick",不是addEventListener中的click
  • attachEvent()注册事件,是在全局作用域中运行,this等于window,而addEventListener注册事件是在其所属元素的作用域内运行。
  • 用attachEvent注册事件只能用detachEvent移除,并且移除时传入的参数必须与注册时相同
  • 用attachEvent注册事件,可以为一个元素同时添加多个事件处理程序,但不是按照添加顺序触发,而是相反顺序触发
  <body>
    <input id="btn" type="button" value="click me">Click</div>
  </body>
  <script>
    var btn = document.getElementById('btn');
    var handler1 = function() {
        console.log(this.value);
    };
   var handler2 = function(){}
    btn.attachEvent("onclick", handler1); //添加事件处理程序handler1
    btn.attachEvent("onclick", handler2); //添加事件处理程序handler2
    btn.detachEvent("onclick", handler1); //移除事件处理程序handler1
    btn.detachEvent("onclick", handler2); //移除事件处理程序handle2
</script>

兼容性:IE和Opera

跨浏览器的事件处理程序和事件对象

以下是以跨浏览器的方式处理事件:

  var EventUtil = {
    //注册事件
    addHandler: function(element, type, handler) {
      if(element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else if(element.attachEvent) {
            element.attachEvent("on" + type, handler);
        } else {
            element["on" + type] = handler;
        }
    },
    //移除事件
    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;
      }
    },
    //获取事件对象
    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(event) {
    if(event.stopPropagation) {
      event.stopPropagation();
     } else {
      event.cancelBubble = true;
     }
   }
};

jQuery注册事件的几种方式

1、$(selector).click(function);
事件处理程序在元素作用域运行,this引用当前元素

$(selector). unbind("click"); //移除事件处理程序

2、$(selector).bind('click');
事件处理程序在元素作用域运行,this引用当前元素,

$(selector). unbind("click"); //移除事件处理程序

3、$(selector).delegate(childSelector, event, data, function);
delegate()方法为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序。使用delegate()方法的事件处理程序适用于当前或者未来的元素(比如脚本创建的元素)。

如下是为iframe里id为ks-dialog-ok元素添加click事件,id为ks-dialog-ok元素是一个弹出框的确认按钮,iframe加载完时id为ks-dialog-ok元素还没有渲染,当触发某个操作弹出框才会渲染,所以需要用delegate为未来的元素绑定事件:

<iframe id="col-web" name="col-web" frameborder="0" width="720px" height="460px" onload="iframeOnload(this)"></iframe>
function iframeOnload(iframe) {
  if(iframe.contentWindow.$) {
    iframe.contentWindow.$(iframe.contentDocument).delegate("#ks-dialog-ok","click",function() {
      $("#flash").hide();
    })
  }
}

4、$(selector).trigger(event, [param1,param2,...])
trigger() 方法触发被选元素的指定事件类型
triggerHandler()同trigger(),但是不可以冒泡
如下,当点击button时,就会触发input的文件上传,当觉得input文件上传按钮比较丑时,就可以自定义button按钮来覆盖原来按钮,利用trigger触发文件上传

<body>
  <button id="btn">点击</button>
  <input type="file">
</body>
<script>
  $('#btn').click(function(){
  $('input').trigger('click');
})
</script>  
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  •   JavaScript 与 HTML 之间的交互是通过事件实现的。   事件,就是文档或浏览器窗口中发生的一些特...
    霜天晓阅读 3,473评论 1 11
  • JavaScript 程序采用了异步事件驱动编程模型。在这种程序设计风格下,当文档、浏览器、元素或与之相关的对象发...
    劼哥stone阅读 1,250评论 3 11
  • JavaScript 与 HTML 之间的交互是通过事件实现的。事件,就是文档或浏览器窗口中发生的一些特定的交互瞬...
    threetowns阅读 339评论 0 0
  • 以下文章为转载,对理解JavaScript中的事件处理机制很有帮助,浅显易懂,特分享于此。 什么是事件? 事件(E...
    jxyjxy阅读 3,023评论 1 10
  • 事件流 JavaScript与HTML之间的交互是通过事件实现的。事件,就是文档或浏览器窗口中发生的一些特定的交互...
    DHFE阅读 822评论 0 3