javascript事件机制与jQuery.bind的补充说明
在之前的文章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"
"">
<html xmlns="" 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"
"">
<html xmlns="" 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"
"">
<html xmlns="" lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src=""></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事件机制与jQuery.bind的补充说明相关推荐
- JavaScript事件机制——细思极恐
JavaScript事件机制,也有让人深思的东西.在一开始未深入了解,我头脑里有几个问题发出: 1. 自下而上(冒泡)事件怎么写,自上而下(捕获)又是怎么写? 2. 捕获型和冒泡型同时设置,谁生效? ...
- 【移动端兼容问题研究】javascript事件机制详解(涉及移动兼容) – 叶小钗
这篇博客有点长,如果你是高手请您读一读,能对其中的一些误点提出来,以免我误人子弟,并且帮助我提高 如果你是javascript菜鸟,建议您好好读一读,真的理解下来会有不一样的收获 在下才疏学浅,文中难 ...
- 【探讨】javascript事件机制底层实现原理
前言 又到了扯淡时间了,我最近在思考javascript事件机制底层的实现,但是暂时没有勇气去看chrome源码,所以今天我来猜测一把 我们今天来猜一猜,探讨探讨,javascript底层事件机制是如 ...
- javascript事件机制
javascript事件机制 ① javascript绑定事件的方式 http://blog.iderzheng.com/dom-javascript-event-binding-comparison ...
- Javascript事件机制兼容性解决方案
本文的解决方案可以用于Javascript native对象和宿主对象(dom元素),通过以下的方式来绑定和触发事件: 或者 var input = document.getElementsByTag ...
- JavaScript事件详解-jQuery的事件实现(三)
正文 本文所涉及到的jQuery版本是3.1.1,可以在压缩包中找到event模块.该篇算是阅读笔记,jQuery代码太长.... Dean Edward的addEvent.js 相对于zepto的e ...
- javascript 事件机制,同步异步
转载自:https://juejin.im/post/59e85eebf265da430d571f89,为了记录方便学习. 这一次,彻底弄懂 JavaScript 执行机制 本文的目的就是要保证你彻底 ...
- JavaScript事件 以及和jQuery中事件使用对比
1.即时反应的input和propertychange方法 :https://www.cnblogs.com/LHYwin/p/6136256.html 2.js自定义一个事件 : htt ...
- jQuery操作Dom、jQuery事件机制、jQuery补充部分
jQuery操作Dom: 修改属性: //使用attr()方法 //attr(name, value) //name:要修改的属性的属性名 //value:对应的值 //attr方法,如果当前标签有要 ...
最新文章
- 【异常】Error: ERROR 1012 (42M03): Table undefined. (state=42M03,code=1012)
- Tips/Tricks#0:母版页中对控件ID的处理
- htmltest~计算器界面的实现
- JAVA中String与StringBuffer的区别
- 【Linux】26.VScode安装、插件、快捷键等基本用法
- 程序员的七种必备武器
- Shell入门(二)之变量
- windows10杀死本地进程
- 时间序列谐波分析(HANTS)的MATLAB实现
- PTC Onshape 的两个核心弱点
- 小卡要民主(卡雷尔机器人)
- Python学习笔记——变量(图灵学院)
- Redis源码阅读笔记(二)list双向链表结构
- 康熙不愧大帝——且看他是怎样交班的
- C++单链表学生管理系统(有登录界面)
- bp神经网络的主要功能,一文搞定bp神经网络
- 特征工程常用于特征提取方法——数值特征
- 计算机教师知识老化,【计算机教学论文】技校计算机教学分析(共2800字)
- 100行python代码实现五子棋-教程
- 现货黄金投资的鳄鱼法则