`

javascript事件机制

阅读更多
http://www.cnblogs.com/345563452/archive/2009/02/10/1387545.html
转自
在之前的文章javascript 事件机制 与 jQuery.Bind中,为了说明冒泡阶段中Event Handler Function的表现,我使用了event.data来记录触发function的次数。并且提出了一个问题,就是在jQuery.bind方式中,event.data无法正确记录触发的次数。后来经过测试和查阅网上的相关的资料,得出了一个结论,就是我之前关于event.data的使用方式是错误的,或者说对于跨浏览器的支持是困难的。同时我也意识到,由于event.data在w3c dom level 2文档中,并不是作为event的标准属性出现的,所以jQuery对event进行了fix,使其能够兼容各个浏览器。

在我纠正误用event.data的方式之前,再描述一下我对event的理解。在我查看jQuery(1.3.2)源代码的时候,jQuery.event的add方法中有如下代码

// Init the element's event structure
var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
    handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function() {
         // Handle the second event of a trigger and when
         // an event is called after a page has unloaded
         return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
                jQuery.event.handle.apply(arguments.callee.elem, arguments) :
                undefined;
        });

其中的jQuery.event.handle中进行event的fix

event = arguments[0] = jQuery.event.fix(event || window.event);

这里按照网上的资料大多是说ie下使用window.event,而firefox下使用arguments[0]也就是传递过来的函数参数 event。可我在测试中发现ie6,ie7(未测试),ie8在fix之前event并不为空,也就是说在fix的时候并没有使用 window.event。

看一下这段代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
<head>    
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"    />
<title></title>
<style>
     #panelGrandPa,#panelPaPa,#panelSon  { border:1px  solid #320213;}
 </style>
</head>
 <body>
<div id="panelGrandPa" style="width:300px;height:200px;" >
       <div id="panelPaPa" style="width:200px;height:100px;" >
            <div id="panelSon" style="width:100px;height:50px;" >
                    
            </div>
       </div>
</div>
<script>
    function click() {
        alert(event.srcElement.id);
        event.data = event.data || 1;
        alert("click function has fired  " + event.data + " times");
        event.data = parseInt(event.data) + 1;
    }
    function clickSon() {
        alert("I am son");
        click();
    }
    function clickGrandPa() {
        alert("I am GrandPa");
        click();
    }
    document.getElementById("panelGrandPa").onclick = clickGrandPa;
    document.getElementById("panelSon").onclick = clickSon;
</script>
</body>
</html>

只能在ie8下正常工作,在ie6和ie7下都报event.data undefined错误。当然我们这里使用的是window.event也就是页面维护的event相当于全局变量,那我们再试一下事件方法的event 参数(之前阅读jQuery源代码提到的ie中除却window.event另外的event)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
<head>    
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"    />
<title></title>
<style>
     #panelGrandPa,#panelPaPa,#panelSon  { border:1px  solid #320213;}
 </style>
</head>
 <body>
<div id="panelGrandPa" style="width:300px;height:200px;" >
       <div id="panelPaPa" style="width:200px;height:100px;" >
            <div id="panelSon" style="width:100px;height:50px;" >
                    
            </div>
       </div>
</div>
<script>
    function click(e) {
        alert(event.srcElement.id);
        e.data = e.data || 1;
        alert("click function has fired  " + e.data + " times");
        e.data = parseInt(e.data) + 1;
    }
    function clickSon() {
        alert("I am son");
        click(arguments[0]);
    }
    function clickGrandPa() {
        alert("I am GrandPa");
        click(arguments[0]);
    }
    document.getElementById("panelGrandPa").attachEvent("onclick", clickGrandPa);
    document.getElementById("panelSon").attachEvent("onclick", clickSon);
</script>
</body>
</html>

注意必须用attachEvent我们才能得到区别于window.event的“另一个”event。以上代码在ie8下正常工作,在ie6和ie7下event.data始终为1


对于window.event,在ie6和ie7下,通过调试工具发现其中并没有event.data的属性。而attachEvent的得到的event.data 在ie6和ie7下不能正确计数,始终为1,但ie8下正确。

鉴于event在各浏览器下的差异以及我们对书写跨浏览器脚本的良好愿望,我个人认为不应该在多个事件方法中传递event.data。

当然jQuery在这方面做得更好经过fix后的event 使得event.data在各种浏览器下表现一致

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
<head>    
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"    />
 <script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.js"></script>
<title></title>
<style>
     #panelGrandPa,#panelPaPa,#panelSon  { border:1px  solid #320213;}
 </style>
<head>
<body>
<div id="panelGrandPa" style="width:300px;height:200px;" >
       <div id="panelPaPa" style="width:200px;height:100px;" >
            <div id="panelSon" style="width:100px;height:50px;" >
                    
            </div>
       </div>
</div>
<script>
    function click(e) {
        alert(e.target.id);
        e.data = e.data || 1;
        alert("click function has fired  " + e.data + " times");
        e.data = parseInt(e.data) + 1;
    }
    function clickSon(e) {
        alert("I am son");
        click(e);
    }
    function clickGrandPa(e) {
        alert("I am GrandPa");
        click(e);
    }
    $("#panelGrandPa").bind("click", clickGrandPa);
    $("#panelSon").bind("click", clickSon);
</script>
</body>
</html>

上述代码在任何浏览器下都不能正常计数,显示event.data为1(这下ie8也不行了)。

我们分析一下原因,这也是我对上一篇提出问题的一个回答

jQuery.event.add方法封装了attachEvent/addEventListener并且给每一个handler方法附加了data

add:function(elem, types, handler, data) {
    //省略部分代码
    // if data is passed, bind to handler
    if (data !== undefined) {
        // Create temporary function pointer to original handler
        var fn = handler;

        // Create unique handler function, wrapped around original handler
        handler = this.proxy(fn);

        // Store data in unique handler
        handler.data = data;
    }
    //省略部分代码
}


在jQuery.event的fix方法中,我们看到其将传入的event复制了一份(包括data),注意不是引用(这意味着每次方法的event都是不同的)

fix: function(event) {
    if (event[expando])
        return event;

    // store a copy of the original event object
    // and "clone" to set read-only properties
    var originalEvent = event;
    event = jQuery.Event(originalEvent);

    for (var i = this.props.length, prop; i; ) {
        prop = this.props[--i];
        event[prop] = originalEvent[prop];
    }
    //以下省略
}

那么这样一来,我们肯定不能在多个事件方法中用上述方法传递data了。
分享到:
评论

相关推荐

    JavaScript事件机制详细研究

    JavaScript 事件机制详细研究 JavaScript 事件机制是指浏览器中发生的各种事件,例如点击、鼠标悬停、键盘输入等,JavaScript 通过捕捉这些事件来执行相应的操作。本文将详细介绍 JavaScript 事件机制的实现方式和...

    【移动端兼容问题研究】javascript事件机制详解(涉及移动兼容)1

    JavaScript 事件机制是网页交互的核心,它使得网页具备响应用户操作的能力。在移动端,考虑到不同设备和浏览器的差异,理解事件机制以及如何处理兼容性问题至关重要。本文将深入探讨JavaScript事件的捕获/冒泡阶段,...

    javaScript事件机制兼容(详细整理).doc

    javaScript事件机制兼容(详细整理).doc

    javaScript事件机制兼容【详细整理】

    JavaScript事件机制是Web开发中的核心概念之一,它负责页面中事件的响应和处理。为了保证在不同的浏览器中能够正确地执行事件处理函数,开发者需要对不同浏览器之间的事件机制兼容性有所了解,并进行相应的处理。...

    javascript事件详解

    总的来说,JavaScript事件是构建动态网页的关键工具,理解并掌握事件处理机制、事件阶段和事件对象的使用,能够帮助开发者编写更高效、更灵活的交互代码。在实际开发中,应充分利用事件委托、事件监听器等高级技巧,...

    JavaScript 事件的一些重要说明

    总结,理解JavaScript事件机制对于编写交互式的网页至关重要。异步回调确保了代码的非阻塞执行,事件对象提供了事件的相关信息,`this`关键字帮助我们定位到事件源,而事件冒泡的管理则让我们能够精确控制事件的传播...

    简析JavaScript事件、以及捕获和冒泡

    本文将深入探讨JavaScript事件机制,特别是事件的捕获和冒泡阶段。 首先,理解JavaScript事件的基础概念至关重要。事件是用户或浏览器在与网页交互时发生的动作,比如点击按钮、页面加载或滚动等。当这些事件发生时...

    js事件机制 .pdf

    ### JavaScript事件机制详解 #### 一、引言 在学习编程语言的过程中,"事件"这一概念往往是初学者遇到的一个难点,然而它又是编程中极为重要的一个组成部分。在JavaScript中,事件处理更是不可或缺的一部分,它是...

    javaScript大事机制兼容(具体整理)_.docx

    在JavaScript中,事件处理机制是网页交互的核心部分,它允许用户与页面进行互动,如点击按钮、提交表单等。本文将详细讲解JavaScript事件机制的兼容性问题,特别是针对不同浏览器(尤其是IE与非IE浏览器)的差异。 ...

    javascript常用事件应用

    通过实践如飞机大战这样的项目,开发者能更深入地理解JavaScript事件机制,从而更好地构建具有互动性和用户体验的网页应用。在学习过程中,不断练习和应用这些知识点,将有助于提升JavaScript编程技能。

    JavaScript的简单且小巧119字节事件发射器库

    标题提到的"JavaScript的简单且小巧119字节事件发射器库"正是这种设计理念的体现,它在极小的代码体积下实现了事件驱动的机制。 事件发射器库,通常包含两个主要功能:注册事件监听器和触发事件。在JavaScript中,...

    JavaScript程序设计——事件处理实验报告.docx

    3. **干预系统的事件处理机制**: - **停止事件冒泡**:通过`event.stopPropagation()`阻止事件继续向上层元素传播。 - **阻止事件的默认行为**:通过`event.preventDefault()`防止默认的浏览器行为,例如阻止链接...

    浅析JavaScript中的事件机制

    接下来,我们将深入探讨JavaScript中的事件机制,这将有助于我们更好地理解如何在网页中实现用户交互。 首先,我们需要明白什么是事件。在计算机编程中,事件是指在运行程序时,某个特定的操作或动作发生时系统所...

    JavaScript王者归来 随书源码

    6. **事件处理**:JavaScript事件机制是用户或浏览器行为的响应机制。通过addEventListener或attachEvent等方法绑定事件处理器,实现用户交互功能,如点击、提交、滚动等。 7. **函数编程**:函数在JavaScript中是...

    JS.zip_javascript

    JavaScript是一种广泛应用于网页和网络应用的脚本语言,主要负责客户端的交互逻辑。在这个"JS.zip_javascript...通过实践和理解这些代码,可以提升对JavaScript事件机制和动态效果实现的理解,从而提升自己的开发能力。

    javascript左右拖曳翻页

    总的来说,实现“javascript左右拖曳翻页”需要深入理解JavaScript事件机制、动画制作以及页面布局。这个过程涉及到的技术点广泛且实用,对于提升用户体验和增强网站互动性有着重要作用。通过不断实践和优化,我们...

    javascript运行机制1

    JavaScript 运行机制 JavaScript 运行机制是指 JavaScript 代码在浏览器或 Node.js 环境中执行的过程。这个机制涉及到变量作用域、函数执行、上下文创建和垃圾回收等多个方面。 一、全局执行上下文 在 JavaScript...

Global site tag (gtag.js) - Google Analytics