JavaScript系列(三)事件

1 事件流

  事件冒泡:当一个元素接收到事件的时候,会把他接收到的所有传播到他的父级,一直传播到window。阻止冒泡:在当前要阻止冒泡的事件函数中调用 event.cancleBubble=true;现代的浏览器中默认使用的是事件冒泡机制,由于老版本不支持事件捕获,所以很少有人使用事件捕获。因此建议使用事件冒泡。

2 事件处理程序

  在DOM中,用于处理指定和删除事件的处理程序的操作:addEventListener()和removeEventListener().在两种方法中,接收三个参数:要处理的事件名、事件处理的函数,选用何种阶段调用事件处理程序。其中第三个参数如果为true的话,则表示在捕获阶段调用事件处理程序,为flase的话,则表明在冒泡的阶段调用事件处理函数。如果为同一个元素添加了多个事件处理程序,那么会按照添加的顺序进行触发。

  两种方法中,其是相生相对的,即通过第一种方法添加的事件处理必须用第二种方法来解除;同时要注意在移除时,所传入的函数必须与添加时所传入的函数相同,这也意味着添加方法中,如果添加匿名函数的化,那么将难以移除。(IE9,Firefox,Safari,Chrome和Opera支持DOM2级事件处理程序)

  在IE中,存在着相对应的attachEvent()和detachEvent(),同时注意在这两种方法中接收:事件处理程序名称和事件处理函数。同时由于IE的特殊性,所以其一般默认添加到冒泡的阶段调用事件处理函数。注意如果为同一元素添加多个事件处理程序,那么会以相反的顺序触发。注意:支持IE事件处理程序的浏览器只有IE和Opera。

  为了处理好跨浏览器的方式处理事件,所以使用一个名叫EventUtil的对象。

var EventUtil = {
    addHandler: function(element, type, handle){
        if(element.addEventListener){
            element.addEventListener(type, handle, false)
        } else if (element.attchEvent){
            element.attachEvent("on" + type, handle)  //为了在IE8及更早版本中运行,事件类型要加上“on”前缀。
        } else{
            element["on" + type] = handle;   //该方法为DOM0使用的方法,一般不会执行该方法。
        }
    },
    removeHandler: function(element, type, handle){
        if(element.removeEventListener){
            element.removeEventListener(type, handle, false)
        } else if (element.detachEvent){
            element.attachEvent("on" + type, handle)
        } else{
            element["on" + type] = null;
        }
    }
}

3 事件对象

 该内容不熟,先跳过。

4 事件类型

  该内容太复杂,先略过。

5 内存和性能

  由于每个函数都是对象,会占用内存,;如果对象过多,那么性能就会越差。其中造成性能过差的原因之一就是事件处理程序过多,所以事件委托机制就产生了。

  事件委托机制利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。以下面为例:

//这是传统的做法var item1 = document.getElementById(‘goSome‘);
var item2 = document.getElementById(‘doSome‘);
var item3 = document.getElementById(‘sayHi‘);

EventUtil.addHandler(item1,‘click‘,function(e){
    location.href = ‘http://www.weibo.com‘;
})
EventUtil.addHandler(item2,‘click‘,function(e){
    document.title = ‘I changed the title‘;
})
EventUtil.addHandler(item3,‘click‘,function(e){
    alert(‘hi‘);
})
//这是事件委托机制下的做法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.cancelBubbles = true;
        }
    },
    getRelatedTarget: function (event) {
        if (event.relatedTarger) {
            return event.relatedTarget;
        } else if (event.toElement) {
            return event.toElement;
        } else if (event.fromElement) {
            return event.fromElement;
        } else { return null; }
    }
};

var list = document.getElementById(‘myLinks‘);

    EventUtil.addHandler(list,‘click‘,function(e){
        event = EventUtil.getEvent(e);
        var target = EventUtil.getTarget(event);
        switch(target.id){
            case "goSome": location.href = ‘http://www.weibo.com‘;    break;
            case "doSome": document.title = ‘I changed the title‘;     break;
            case "sayHi": alert(‘hi‘);    break;
        }
    });

  在上个代码中,只为ul元素添加一个点击事件。在ul元素下的li中,其会冒泡,所以li的点击都会被这个函数所处理。由于其只取得一个DOM元素,所以占用的内存更少,所有用到按钮的事件都适合采用事件委托技术。

  新的做法与传统的做法有几个优点:

  (1)document对象很快可以访问。而且可以在页面生命周期的任何时点上围棋添加事件处理程序(不需要DOMContentLoaded或load事件)。即如果可以点击的元素呈现在页面上,便可以具备相应的功能。

  (2)在页面中设置事件处理程序所需的时间更少。

  (3)提升整体性能。

  能够采用事件委托技术的事情包括click、mousedown、mouseup、keydown、keyup和keypress。虽然mouseover和mouseout事件也冒泡,但是经常要计算其元素的位置,所以不建议使用。

  为了提高整体性能,除了可以使用事件委托机制以外,还可以在不需要的时候移除事件处理程序。

该套方法还是不太熟悉,再跳过。

6 模拟事件

  

 

时间: 2024-10-10 10:13:32

JavaScript系列(三)事件的相关文章

JavaScript系列之事件冒泡机制简介

JavaScript系列之事件冒泡机制 DOM事件流(event flow )存在三个阶段:事件捕获阶段.处于目标阶段.事件冒泡阶段,事件冒泡顺序是由内到外进行事件传播,事件冒泡是由IE开发团队提出来的,即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播. 听了简介介绍之后,您可能不理解,所以举个例子: <html> <head> <title>js事件冒泡测试</title> </head> <body>

JavaScript系列三:JavaScript内置对象

1.什么是对象 JavaScript 中的所有事物都是对象,如:字符串.数值.数组.函数等,每个对象带有属性和方法. 对象的属性:反映该对象某些特定的性质的,如:字符串的长度.图像的长宽等: 对象的方法:能够在对象上执行的动作.例如,表单的"提交"(Submit),时间的"获取"(getYear)等: JavaScript 提供多个内建对象,比如 String.Date.Array 等等,使用对象前先定义,如下使用数组对象: 访问对象属性的语法: objectNam

JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数

本篇体验JavaScript事件的基本面,包括: ■ 事件必须在页面元素加载之后起效■ 点击事件的一个简单例子■ 为元素注册多个点击事件■ 获取事件参数 □ 事件必须在页面元素加载之后起效 有这样一段简单的代码: <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <style>

javaScript中的事件三

javaScript中的事件三 先看两种错误的写法,他们的目的都是:添加两个事件: 错误方式一: window.onload=function (){ alert('event 1'); } window.onload=function (){ alert('event 2') } 错误方式二: window.onload=function (){ var obj=document.getElementById("but"); obj.onclick=function(){ alert

JavaScript进阶系列06,事件委托

在"JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数"中已经有了一个跨浏览器的事件处理机制.现在需要使用这个事件处理机制为页面元素注册事件方法. □ 点击页面任何部分触发事件 创建一个script1.js文件. (function() { eventUtility.addEvent(document, "click", function(evt) { alert('hello'); }); }(

javascript中定义事件的三种方式

在javascript中,可以为某个元素指定事件,指定的方式有以下三种: 1.在html中,使用onclick属性 2.在javascript中,使用onclick属性 3.在javascipt中,使用addEvenListener()方法 三种方法的比较 (1)在第二.三种方法中,可以向函数传入一个event对象,并读取其相应属性,而方法一不可以. (2)首选第二.三种,第一种不利于将内容与事件分离,也不能使用event对象的相关内容. 一些语法细节 (1)在第一种方法中,onclick大小写

javascript系列之核心知识点(一)

JavaScript. The core. 1.对象 2.原型链 3.构造函数 4.执行上下文堆栈 5.执行上下文 6.变量对象 7.活动对象 8.作用域链 9.闭包 10.this值 11.总结 这篇文章是"ECMA-262-3 in detail"系列的一个摘要和总结.每一部分包含了对应章节的连接引用,所以你可以仔细去阅读得到一个更深刻的理解.适合的读者:资深程序员,专家.我们从探讨对象的概念开始,这也是ECMAScript的奠基石. 对象 ECMAScript,一个高度抽象的面向

深入理解JavaScript系列(24):JavaScript与DOM(下)

介绍 上一章我们介绍了JavaScript的基本内容和DOM对象的各个方面,包括如何访问node节点.本章我们将讲解如何通过DOM操作元素并且讨论浏览器事件模型. 本文参考:http://net.tutsplus.com/tutorials/javascript-ajax/javascript-and-the-dom-lesson-2/ 操作元素 上一章节我们提到了DOM节点集合或单个节点的访问步骤,每个DOM节点都包括一个属性集合,大多数的属性都提供为相应的功能提供了抽象.例如,如果有一个带有

深入理解JavaScript系列(10):JavaScript核心(晋级高手必读篇)

本篇是ECMA-262-3 in detail系列的一个概述(本人后续会翻译整理这些文章到本系列(第11-19章).每个章节都有一个更详细的内容链接,你可以继续读一下每个章节对应的详细内容链接进行更深入的了解. 适合的读者:有经验的开发员,专业前端人员. 原作者: Dmitry A. Soshnikov 发布时间: 2010-09-02 原文:http://dmitrysoshnikov.com/ecmascript/javascript-the-core/ 参考1:http://ued.ctr

深入理解JavaScript系列(6):S.O.L.I.D五大原则之单一职责SRP

前言 Bob大叔提出并发扬了S.O.L.I.D五大原则,用来更好地进行面向对象编程,五大原则分别是: The Single Responsibility Principle(单一职责SRP) The Open/Closed Principle(开闭原则OCP) The Liskov Substitution Principle(里氏替换原则LSP) The Interface Segregation Principle(接口分离原则ISP) The Dependency Inversion Pr