Javascript 回调和事件(翻译)(3)
作者:mingcheng 来源:gracecode.com 发布时间:2009-03-28 11:47:00
解决方案
我想到了个解决方案,就是将回调和事件结合起来。可以先建立个事件,当回调触发时才运行它。由于每个事件都有其独立的运行环境(execution context),那么即使其中某个事件抛出了异常将不会影响其他的回调。
这听起来有点复杂,还是代码说话吧。
var currentHandler;// 标准事件支持if (document.addEventListener) { document.addEventListener("fakeEvents", function() { // 执行回调 currentHandler(); }, false); // 新建事件 var dispatchFakeEvent = function() { var fakeEvent = document.createEvent("UIEvents"); fakeEvent.initEvent("fakeEvents", false, false); document.dispatchEvent(fakeEvent); };} else { // 针对 IE 的代码在后面详细阐述}var onLoadHandlers = [];// 将回调加入数组中function addOnLoad(handler) { onLoadHandlers.push(handler);};// 逐条取出回调,并利用上述新建的事件执行onload = function() { for (var i = 0; i < onLoadHandlers.length; i++) { currentHandler = onLoadHandlers[i]; dispatchFakeEvent(); }};
万事俱备,让我们将上面坨代码扔到我们新的回调系统中
addOnLoad(function() { console.log("Init: 1"); DOES_NOT_EXIST++; // 这里会抛出异常});addOnLoad(function() { console.log("Init: 2");});
上帝保佑,看运行结果我们看到了如下的信息:
Init: 1Error: DOES_NOT_EXIST is not definedInit: 2
赞!这就是我们期望的。这两个回调都运行而且互不影响,并且还能获得异常的信息,太好了!
好了,我们回过头来扶起 Internet Explorer 这个“阿斗”(我已经听见场下观众的建议了)。Internet Explorer 不支持 W3C 的标准事件规范,谢天谢地好在它有自身的实现 -- 有个 fireEvents 的方法,但只能在用户事件的时候触发(例如用户点击 click)。
不过终于找到了门道,我们来看下具体代码:
var currentHandler;if (document.addEventListener) { // 省略上述的代码} else if (document.attachEvent) { // MSIE // 利用扩展属性,当此对象被改变时触发 document.documentElement.fakeEvents = 0; document.documentElement.attachEvent("onpropertychange", function(event) { if (event.propertyName == "fakeEvents") { // 执行回调 currentHandler(); } }); dispatchFakeEvent = function(handler) { // 触发 propertychange 事件 document.documentElement.fakeEvents++; };}
简而言之,殊途同归,只是针对 Internet Explorer 使用了 propertychange 事件作为触发器。
猜你喜欢
- 设置MySQL数据同步(单向&双向)由于公司的业务需求,需要网通和电信的数据同步,就做了个MySQL的双向同步,记下过程,以后用得到
- 我们可用ADO STREAM来做一个无组件的上传程序。Stream对象包含了许多操作二进制和文本文件的方法,我们现在用Stream对象来操作
- 依次前移,实现聊友们的发言的更迭:function form1_onsubmit()if document.form1.
- IFRAME 元素 | iframe 对象创建内嵌浮动框架。成员表下面的表格列出了 iframe 对象引出的成员。请单击左侧的标签来选择你想
- 代码如下:< % Set fso=Server.CreateObject("Scripting
- 写入:1:把gif图像文件读入内存(一个变量strTemp)。2:写入数据库。Dim binTmp() As ByteDim conn As
- 著名的老掉牙的IE6.0在我这里已经有六年工龄了,前几天朋友拿到个IE8.0新的Beta版本,我的Sever2003装不上,大为扫兴。Chr
- 在 MySQL 中,数据库和表对应于那些目录下的目录和文件。因而,操作系统的敏感性决定数据库和表命名的大小写敏感。这就意味着数据库和表名在
- 支付宝lab的意思是支付宝实验室,也就是概念产品聚集地,可以让用户快速试用这些新产品。本次支付宝lab logo设计历时一个星期,视觉设计组
- 作者:Scott Gerber原标题:Mobile App Development: 10 Tips for Small Business
- 输入汉字提示拼音,试试下面这个函数,不知是不是你要的那个:查询汉字便宜到词典网<%function getpychar(ch
- 定义列表和其他类型的列表稍有不同,它由两部分组成:名称和定义。DT 指定名称,为内联元素。DD 指定定义,为块级元素。标准属性id, cla
- 现在正在搞三层开发,用ASP和VB6.0,但是现在苦于没有找到合适的方法来调试自己写的DLL文件,效率相当低。 &n
- 首先,大家先去下载一份dvbbs.php beta1的代码,解压后先抛开php代码,找出你的mysql手册,如果没有手册那么就直接看下面的实
- 参数strSQL 要导出的SQL查询语句strFields 字段名称列表,如果为空字符,则使用SQL语句中的字段名用法示例:1:export
- 如果你是个赛车手,并且按一下按钮就能够立即更换引擎而不需要把车开到车库里去换,那会是什么感觉呢?MySQL数据库为开发人员所做的就好像是按按
- XML同HTML一样,都来自Standard Generalized Markup Language, 即标准通用标记语言,简称SGML。早
- 用ASP生成XBM数字图片(可用来生成验证码)XBM图片是一个纯文本的文件,可以用ASP来自动生成。可以用它来使用网站登陆的验证码;我们用记
- 淘宝商城的 detail 页面“产品详情”部分是商家自定义区块,曾出现这样一个问题:推荐:css行高:line-height属性详解 <
- 在ASP中,除了ADODB、Scripting 等一些常用组件外,我们还可以用微软的ActiveX方法来轻松捕获哟: <%u