- 浏览: 1172258 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
zhizhen23:
LZ 提供的链接地址失效了
重写的isPlainObject方法 -
LovingBaby:
LovingBaby 写道function fun() {}f ...
读jq之二(两种扩展) -
LovingBaby:
说的很清楚!jQuery作者为了实现简洁调用的苦心!高超的编程 ...
读jq之一(jq对象的组成) -
hard_ly:
...
将伪数组转换成数组 -
zlxzlxzlxzlxzlx:
这不能算是任意进制之间的转换,例如二十六进制、十二进制又该如何 ...
用递归实现十进制数转换N进制
事件对象的获取很简单,很久前我们就知道IE中事件对象是作为全局对象( window.event )存在的,Firefox中则是做为句柄( handler )的第一个参数传入内的。所以一行代码就可以搞定,如:
var evt = window.event || arguments[0];
下面分三种添加事件的方式讨论
1,第一种添加事件的方式,直接在html的属性中写js代码
<div onclick="alert(4);">Div1 Element</div>
大概这是上世纪90年代的写法,那时候直接把js代码写在网页中很普遍,也许那时候的js并不太重要,只是用来做做验证或一些花哨的效果而已。
如何在这种添加事件方式下获取到事件对象?
IE中很简单,因为event是作为全局对象的,所以直接使用event即可,如下:
<div onclick="alert(window.event.type);">Div1 Element</div>
点击该Div后,IE中会弹出'click'字符的信息框。说明事件对象获取到了,如果在 Opera/Safari/Chrome 中也测试了,会发现效果和IE一样,说明 Opera/Safari/Chrome 中也支持IE方式( window.event )获取事件对象。
Firefox中会报错,提示:window.event is undefined,说明Firefox不支持IE方式获取事件对象而是以句柄的第一个参数传入的,文章开头已经提到了。
上面的用 window.event 来获取事件对象,其实window可以省略的,就像使用alert而不是window.alert一样。如:
<div onclick="alert(event.type);">Div1 Element</div>
在 IE/Opera/Safari/Chrome 中测试,和刚刚不会有什么区别。在Firefox中再测,会有个惊喜,你会发现居然弹出的是"click"信息框,而不是"undefined"。
两次测试区别仅仅一个用window.event.type,一个用event.type。这个问题一会儿详细讨论。
下面用句柄第一个参数来获取事件对象,可以把onclick属性的值想象成一个匿名函数,onclick属性值的字符串实际上都是这个匿名函数内的js代码。
既然这样,我们就可以通过Function的一个属性argumengs获取到该匿名函数的第一个参数,而该参数就是事件对象。如下:
<div onclick="alert(arguments[0].type);">Div1 Element</div>
IE中会报错,提示:arguments.0.type为空或不是对象
Firefox/Opera/Safari/Chrome 中会弹出"click"内容的信息框,说明他们都支持事件对象作为句柄第一个参数传入。从侧面也说明了 Opera/Safari/Chrome 不仅支持W3C标准方式获取事件对象,同时也兼容了IE方式获取事件对象。
既然知道onclick对应的是一个匿名函数,我们不妨把该匿名函数打印出来看看,只需以下代码:
<div onclick="alert(arguments.callee);">Div1 Element</div>
在各浏览器中点击该Div,结果如下:
IE6/7/8 :
function onclick(){ alert(arguments.callee);}
IE9 :
function onclick(event){ alert(arguments.callee);}
Firefox / Safari :
function onclick(event) { alert(arguments.callee);}
Chrome :
function onclick(evt) { alert(arguments.callee);}
Opera :
function anonymous(event) {alert(arguments.callee);}
观察这些函数发现:
IE6/7/8没有定义参数
IE9/Firefox/Safari/Opera 定义了参数event
Chrome定义了参数evt。
现在回到上面遗留的问题,如下:
<div onclick="alert(window.event.type);">Div1 Element</div> <div onclick="alert(event.type);">Div1 Element</div>
这两个div的区别仅window.event.type和event.type。分别点击后,后者在Firefox中不弹出"undefined",而是"click",是因为Firefox中匿名函数定义了参数event,该参数刚好与IE的全局对象event同名,从而误以为Firefox也支持IE方式获取事件对象。
同样的道理,Chrome中定义的参数是evt,那么在Chrome中还可以通过以下方式获取事件对象,如下:
<div onclick="alert(evt);">Div1 Element</div>
2,第二种添加事件的方式,定义一个函数,赋值给html元素的onXXX属性
<script type="text/javascript"> function clk(){} </script> <div onclick="clk()">Div2 Element</div>
先定义函数clk,然后赋值给onclick属性,这种方式也应该属于上世纪90年代的流行写法。比第一种方式好的是它把业务逻辑代码都封装在一个函数里了,使html中的html代码与js代码稍微有点儿分离,不至于第一种那么紧密耦合。
如何在这种方式(clk函数内)中获取事件对象?
IE中使用全局对象event仍然没问题,如:
<script type="text/javascript"> function clk(){alert(window.event);} </script> <div onclick="clk()">Div2 Element</div>
点击Div后,除Firefox外,IE/Opera/Safari/Chrome都能正常获取事件对象。上面已经提到了 Opera/Safari/Chrome 兼容IE方式(window.event)获取事件对象,而唯独Firefox不支持。从而Firefox中只能通过参数传入了。
试着这么写:
<script type="text/javascript"> function clk(){alert(event);} </script> <div onclick="clk()">Div2 Element</div>
因为在Firefox中匿名函数是具有event参数的,而clk()是在匿名函数之内的,打印出匿名函数便知:
<script type="text/javascript"> function clk(){alert(arguments.callee.caller);} </script> <div onclick="clk()">Div2 Element</div>
点击该Div,Firefox弹出信息框内容如下:
function onclick(event) {
clk();
}
回到clk中的alert(event),既然匿名函数的event传入了,那么在该闭包中clk是可以获取到event的,事实上点击后Firefox会报错:event is not defined。猜测该匿名函数的闭包和function clk(){alert(event);}不是同一个闭包环境。
这种方式不行,则只能通过显示的参数传入了,如:
<script type="text/javascript"> function clk(e){alert(e);} </script> <div onclick="clk(arguments[0])">Div2 Element</div>
点击Div,在Firefox中正确弹出了事件对象,支持参数传入的浏览器都可以,如Opera/Safari/Chrome。
当然,
把以上代码中的arguments[0]改成event,那么所有浏览器都支持。
把以上代码中的arguments[0]改成window.event,那么将只有Firefox不支持。
把以上代码中的arguments[0]改成evt,那么将只有Chrome支持。
思考下为什么?
3,第三种添加事件方式,使用element.onXXX方式
<div id="d3">Div3 Element</div> <script type="text/javascript"> var d3 = document.getElementById('d3'); d3.onclick = function(){ } </script>
这种方式也比较早期,但好处是可以将JS与HTML完全分离,但前提是需要给html元素提供一个额外的id属性(或其它能获取该元素对象的方式)。
这种方式添加事件IE6/7/8只支持window.event不支持参数传入,Firefox只支持参数传入不支持其它方式。IE9/Opera/Safari/Chrome 两种方式都支持。
4,第四种添加事件方式,使用addEventListener方式或IE专有attachEvent方式
<div id="d4">Div4 Element</div> <script type="text/javascript"> var d4 = document.getElementById('d4'); function clk(){alert(4)} if(d4.addEventListener){ d4.addEventListener('click',clk,false); } if(d4.attachEvent){ d4.attachEvent('onclick',clk); } </script>
这是目前推荐的方式,较前两种方式功能更为强大,可以为元素添加多个句柄(或称响应函数),支持事件冒泡或捕获,前两种方式默认都是冒泡。
当然IE6/7/8仍然没有遵循标准而使用了自己专有的attachEvent,且不支持事件捕获。IE9
中已经支持addEventListener了。
先用window.event测试,如:
<script type="text/javascript"> var d4 = document.getElementById('d4'); function clk(){alert(window.event)} if(d4.addEventListener){ d4.addEventListener('click',clk,false); } if(d4.attachEvent){ d4.attachEvent('onclick',clk); } </script>
点击Div[id=d4],IE/Opera/Safari/Chrome都正确的弹出了事件对象信息框,Firefox弹出的是"undefined",预料之中,因为Firefox不支持window.event作为事件对象。
再换成句柄的第一个参数测试,如:
<script type="text/javascript"> var d4 = document.getElementById('d4'); function clk(e){alert(e)} if(d4.addEventListener){ d4.addEventListener('click',clk,false); } if(d4.attachEvent){ d4.attachEvent('onclick',clk); } </script>
测试之前,猜测一下什么结果,可能有人会觉得IE中应该弹出undefined,其它浏览器都是事件对象。事实上所有浏览器弹出的信息框显示都是事件对象。
最后的最后总结下:
1,IE支持通过window.event获取对象,通过attachEvent方式添加事件时也支持事件对象作为句柄第一个参数传入
2,Firefox只支持事件对象作为句柄第一个参数传入
3,Opera/Safari/Chrome两种方式都支持
IE6/7/8 | IE9 | Firefox | Opera | Safari | Chrome | |
第一种方式添加事件 |
window.event event |
window.event event arguments[0] |
event, arguments[0] |
window.event event arguments[0] |
window.event event arguments[0] |
window.event event arguments[0] evt |
第二种方式添加事件 |
window.event event |
window.event event arguments[0] |
arguments[0] |
window.event event arguments[0] |
window.event event arguments[0] |
window.event event arguments[0] |
第三种方式添加事件 |
window.event event |
window.event event arguments[0] |
arguments[0] |
window.event event arguments[0] |
window.event event arguments[0] |
window.event event arguments[0] |
第四种方式添加事件 |
window.event event arguments[0] |
window.event event arguments[0] |
arguments[0] |
window.event event arguments[0] |
window.event event arguments[0] |
window.event event arguments[0] |
评论
我目前是4种方式都用。
因为是给企业开发,关于浏览器的适用性一般要保证IE6,IE7上正常,对于FireFox有些不支持,却很少分析原因或者找出其特征。看来得注意一下了
发表评论
-
仅Firefox中A元素包含Select时点击Select不能选择option
2014-09-26 11:03 1417这是在使用京东的一个日期组件时碰到的bug,重现bug的代码 ... -
IE11的API变化
2014-06-10 15:40 1265IE11已经登陆Win8.1,它的API有了很大变更 ... -
Button未设type属性时在非IE6/7中具有submit特性
2014-06-04 12:01 808如下 <!DOCTYPE html> < ... -
光标从编辑器移入本页面中的其它输入域后,IE中每次只在编辑器首部插入内容
2013-11-25 08:10 1051做编辑器开发时碰到的 重现步骤: 1. 将光标 ... -
仅IE6/7不支持字符串属性/索引读取
2013-05-31 14:35 1161IE6/7不支持字符串属性/索引读取(Property ac ... -
IE9/Firefox/Safari/Chrome/Opera支持模拟触发自定义DOM事件
2013-05-30 13:57 1278自定义DOM事件是在DOM3中定义的,它不是由DOM原生触发 ... -
各浏览器中innerHTML实现差异(2)
2012-05-17 07:40 1335如下代码 <p id="tit&q ... -
各浏览器中innerHTML实现差异(1)
2012-05-16 06:59 1564如下代码 <p id="tit&quo ... -
xhrhttprequest部分浏览器中不支持put/delete
2012-04-16 20:59 3020后端同事想采用REST风格,hailiang在看jQuery文 ... -
仅IE6/7浏览器SPAN元素包含块级元素会使SPAN的背景色显示
2012-02-23 18:19 1524这个bug发生在下面的网页,如下: http://yy ... -
设置iframe为可编辑状态后敲回车在各浏览器中输出的innerHTML不同
2012-02-14 18:57 2313测试代码如下 <!doctype html> ... -
设置iframe的document.designMode后仅Firefox中其body.innerHTML为br
2012-02-14 14:30 2881设置iframe的document.designMode为On ... -
各浏览器中for in顺序的差异
2012-02-06 20:04 1568这个问题在sohu博客中也有:写博客-插入图片图片顺序在Chr ... -
IE6/7不支持hashchange事件
2011-11-11 13:51 1527如下 <!doctype html> & ... -
设置元素浮动的几种方式
2011-11-10 11:25 1692们知道获取元素的浮动属性,各浏览器中使用的属性不同。大家都知道 ... -
textarea元素IE6/7/8/9/10中默认有上下滚动条
2011-11-10 11:19 1723IE下有上下滚动条。其它浏览器没有。先看一个示例 &l ... -
各情景下元素宽高的获取
2011-11-09 12:20 1841为了叙述简单,这里仅拿width示例。 情景一, ... -
元素未显示设置width/height时IE中无法使用currentStyle获取(默认为auto)
2011-11-09 12:13 1369我们知道获取元素的实际宽高在IE中可以使用currentSty ... -
各浏览器中使用getAttribute获取checkbox/radio的checked值不同
2011-11-08 21:18 1946如下 <!DOCTYPE HTML> < ... -
IE6/7不支持setAttribute设置style / 不支持getAttribute获取style属性值
2011-11-08 09:39 1569IE6/7中不能通过setAttribute设置元素的s ...
相关推荐
Spring的IoC容器在这些基础上提供了更多高级服务,比如bean的实例缓存、生命周期管理、代理、事件发布和资源加载等。 Spring的高层容器视图展示了容器启动时如何读取应用提供的配置信息,生成bean配置注册表,然后...
在Vuex全家桶中,我们主要关注 State、Mutations 和 Actions。 1. **State**:State 用于存储应用程序的所有共享状态。在 Vuex 中,所有的状态都应被集中到一个单一的对象(store)中。例如,你可以创建一个 `list`...
"Spring Boot全家桶配置"这个主题涵盖了Spring Boot与其他重要技术的整合,包括Redis、JPA、MongoDB和Dubbo,这些技术都是现代微服务架构中的关键组件。下面我们将深入探讨这些技术及其在Spring Boot中的应用。 1. ...
2. IMAP(Internet Message Access Protocol):互联网邮件访问协议,允许用户从邮件服务器获取邮件信息、下载邮件。与POP3相比,IMAP支持双向通信,意味着客户端的操作(如阅读、标记已读等)会同步到服务器上。 3...
### 机器视觉全家福之OPENNI 2.0编程简要说明 #### 一、概述 本篇将详细介绍OPENNI 2.0编程的核心概念及其使用方法,旨在为开发者提供一个全面了解OPENNI 2.0框架的指南。OPENNI 2.0是一款开放源代码的软件框架,...
2023最新Spring全家桶面试题-图灵徐庶 本文将对Spring全家桶面试题进行详细的解析,从Spring Framework到Spring MVC,涵盖了SpringIOC、AOP、事务、Beans等多个方面。 一、Spring Framework 1. 对Spring的理解:...
在本节“Vue全家桶-项目实战(下)1”中,主要讲解了如何使用Vue.js框架进行后台管理系统中的用户管理模块的开发。这个模块涵盖了用户信息的展示、增删改查、状态控制以及角色分配等功能。以下是详细的知识点解析: ...
3. Event 对象:Event 对象是 React 中的事件对象,包含了事件相关的信息。 六、Ref 的应用 1. 给标签设置 ref:可以通过 ref 属性将标签实例保存到变量中。 2. 给组件设置 ref:可以通过 ref 属性将组件实例保存...
"全家桶"通常意味着包含了该库的所有组件和必要的依赖,这里特别提到了"so"文件,这在Linux系统中代表共享对象文件,是Java本地接口(JNI)在Linux环境下使用的动态链接库。 描述进一步解释了这个资源的内容:“sap...
4. **类与对象**:深入讲解面向对象编程的基础,包括类的定义、对象的创建、封装、继承和多态。 5. **数组**:介绍一维和多维数组的概念,以及如何操作和遍历数组。 6. **异常处理**:学习如何使用try-catch-...
还有可能使用audio元素来处理音频播放控制,通过监听事件和操作audio对象来实现播放、暂停、进度控制等功能。 最后,项目构建和部署也是一个重要环节。Vue CLI支持配置Webpack,用于模块打包和优化,如代码分割、...
- `connect()`函数允许我们将React组件连接到Redux store,这样组件可以获取state并触发actions。 ```javascript import { Provider, connect } from 'react-redux'; import { createStore } from 'redux'; const ...
1. **视频流处理**:通过摄像头获取实时视频流,可能涉及视频编码和解码技术。 2. **图像分析**:利用计算机视觉算法,如物体检测、人脸识别等,进行智能分析。 3. **数据存储**:保存视频流、分析结果等数据,可能...
在这个“Vue全家桶之Vuex实例代码”中,我们将探讨Vuex的核心概念以及如何通过实际代码来理解它们。首先,Vuex由几个核心概念组成:state、mutations、actions、getters 和 modules。 1. **State**:状态是Vuex中的...
这个方法打开一个文本文件,返回一个`TextStream`对象,通过该对象的`ReadLine`方法可以逐行读取文件内容。如果需要读取整个文件,可以使用`ReadAll`方法一次性读取所有内容。 在VB中,文件操作通常需要处理异常,...
【Vue全家桶-项目上线1】的描述涵盖了多个关于项目优化和上线的步骤,以下是这些知识点的详细说明: 1. **生成打包报告**:在项目优化过程中,生成打包报告是了解项目性能瓶颈的重要手段。通过运行`vue-cli-service...
3. **Mongoose**:MongoDB的ODM(对象文档映射),提供了强大的数据模型设计和操作接口。 4. **NPM**:Node包管理器,用于安装、管理依赖包和发布自定义模块。 5. **JWT(JSON Web Tokens)**:用于安全地在客户端和...
这个项目可能是一个简易的豆瓣电影(Douban Movie)克隆版,用于展示如何将前端与后端完美结合,实现数据的动态获取和交互。 首先,Vue.js是当前非常流行的渐进式JavaScript框架,它允许开发者创建用户界面并管理...
物联网(IoT)是信息科技产业中一个迅速成长的领域,涉及通过传感器、软件及其他技术,让物理对象相互连接与交换数据的网络。以下是关于物联网行业的关键知识点。 1. 物联网的基本概念:物联网(Internet of Things)...
它支持类和接口,使得面向对象编程更加规范。此外,TypeScript还支持ES6+的新特性和装饰器,这些特性在现代JavaScript开发中非常常见。 4. **项目结构**:项目名“vue-typescript-music-master”表明项目可能有一个...