- 浏览: 338477 次
- 性别:
- 来自: 厦门
文章分类
最新评论
-
弦月001:
我目前也是碰到这样的情况,在jsp里面没有问题,但在free ...
Spring+Freemarker(国际化) -
laj12347:
zhangsw_00 写道我参照你的方法,配置环境,在jsp文 ...
Spring+Freemarker(国际化) -
yctan:
hi,能不能把发送邮件的代码也贴一下啊。
用webdav协议访问exchange邮件服务器,下载附件的问题 -
maketc:
楼上正解,这个问题也被郁闷了半天,试过重启tomcat、ecl ...
Tomcat 部署 Could not copy all resources to 或者Undeployment Failure could not be re -
masuweng:
楼上正解,这个问题曾被郁闷了半天
Tomcat 部署 Could not copy all resources to 或者Undeployment Failure could not be re
IE的 JScript 存在内存泄露的bug 想必大家都清楚或者有耳闻了。这是由于IE的内存回收管理器的一个设计错误导致的。当我们编写脚本的时候创建了交叉引用,例如如下代码: window.onload = function () {
var x = document.getElementsByTagName(’H3’);
for (var i=0;i<x.length;i++)
{
x[i].onclick = openClose;
x[i].relatedElement = x[i].nextSibling; // simplified situation
x[i].relatedElement.relatedElement = x[i];
}
}或者在函数中使用脚本语言最常见的闭句Closures的时候,IE都无法回收内存。而闭句在给DOM对象注册事件处理器(event handler)的时候最为常用。Novemberborn提供了一些example可以让你运行并切实感受到这个bug。
我最喜爱的QuirkMode 去年初意识到这个bug存在巨大隐患,觉得有必要呼吁广大web开发者关注并竭力避免这个问题,于是举办了一个慈善邀请赛,鼓励大家提交各自addEvent/removeEvent 方案。并终于在去年10月下旬宣布了他们认为的胜利者:John Resig,让 John赢得胜利的代码如下:
function addEvent( obj, type, fn ) {
if ( obj.attachEvent ) {
obj[’e’+type+fn] = fn;
obj[type+fn] = function(){obj[’e’+type+fn]( window.event );}
obj.attachEvent( ’on’+type, obj[type+fn] );
} else
obj.addEventListener( type, fn, false );
}
function removeEvent( obj, type, fn ) {
if ( obj.detachEvent ) {
obj.detachEvent( ’on’+type, obj[type+fn] );
obj[type+fn] = null;
} else
obj.removeEventListener( type, fn, false );
}
QuirkMode 对选择John为胜利者的解释概括来说就是以上代码最简洁有效,在避免内存问题的同时还巧妙的保证了this关键字在ie的attachEvent中能正常工作。缺点当然还是存在:
不支持 Netscape 4 和 Explorer 5 Mac。(有可能国内的程序员会嗤之以鼻,但国外很强调广泛的兼容性)
在 removeEvent 中遗漏了remove obj["e"+type+fn]。
总之不管怎么说,简单取胜。
结果一出,众多参赛与评论者不服气,很快又挑出了John的代码的几处毛病:
addEvent中本身就使用了闭句,所以没有根本解决IE内存泄露的问题。
没有解决同类型的事件可能被重复注册而被IE重复执行的问题。
几个高手于是提出了改进性的方案: /*
Original idea by John Resig
Tweaked by Scott Andrew LePera, Dean Edwards and Peter-Paul Koch
Fixed for IE by Tino Zijdel (crisp)
Note that in IE this will cause memory leaks and still doesn’t quite function the same as in browsers that do support the W3C event model:
- event execution order is not the same (LIFO in IE against FIFO)
- functions attached to the same event on the same element multiple times will also get executed multiple times in IE
*/
function addEvent( obj, type, fn ) {
if (obj.addEventListener)
obj.addEventListener( type, fn, false );
else if (obj.attachEvent) {
obj["e"+type+fn] = fn;
obj.attachEvent( "on"+type, function() { obj["e"+type+fn](); } );
}
}
function removeEvent( obj, type, fn ) {
if (obj.removeEventListener)
obj.removeEventListener( type, fn, false );
else if (obj.detachEvent) {
obj.detachEvent( "on"+type, obj["e"+type+fn] );
obj["e"+type+fn] = null;
}
}
很明显,虽然修正了John代码的一些不足。但内存泄露依然存在,部分浏览器依然不支持,还是无法避免ie重复注册。另外根据注释:当在同一个对象上注册多个事件处理器的时候,IE与其他浏览器的执行顺序是不同的,这又是一个隐患。
几天之后,一个被认为最严谨的方案由Dean Edwards 提出。Dean他的方案与众不同:
不执行对象检测(Object detection)
没有调用 addeventListener/attachEvent 方法
保持this关键字的运行于正确的上下文环境
正确传递 event 对象参数
完全跨浏览器至此(包括IE4和NS4)
不存在内存泄露
Dean的代码如下: // written by Dean Edwards, 2005
// http://dean.edwards.name/function ;addEvent(element, type, handler) {
// assign each event handler a unique ID
// 为事件处理函数设定一个唯一值
if (!handler.$$guid) handler.$$guid = addEvent.guid++;
// create a hash table of event types for the element
if (!element.events) element.events = {};
// create a hash table of event handlers for each element/event pair
var handlers = element.events[type];
if (!handlers) {
handlers = element.events[type] = {};
// store the existing event handler (if there is one)
// 如果对象已经注册有事件处理,那么要保留下来,并保存为第一个
if (element["on" + type]) {
handlers[0] = element["on" + type];
}
}
// store the event handler in the hash table
handlers[handler.$$guid] = handler;
// assign a global event handler to do all the work
// 指派一个全局函数做统一的事件处理,同时避免了反复注册
element["on" + type] = handleEvent;
};
// a counter used to create unique IDs
addEvent.guid = 1;function removeEvent(element, type, handler) {
// delete the event handler from the hash table
if (element.events && element.events[type]) {
delete element.events[type][handler.$$guid];
}
};function handleEvent(event) {
// grab the event object (IE uses a global event object)
event = event || window.event;
// get a reference to the hash table of event handlers
// 这里的 this 随 handlerEvent function 被触发的source element 变化而变化
var handlers = this.events[event.type];
// execute each event handler
for (var i in handlers) {
//这样写才能保证注册的事件处理函数中的 this 得到正确的引用,直接handlers[i]()是不行的
this.$$handleEvent = handlers[i];
this.$$handleEvent(event);
}
};
这段代码相比之前就大了不少了,不过确实很精妙。可是这段代码却引入了其他的问题,比如无法处理事件处理函数的返回值,for..in循环可能因为(Object.prototype)的错误应用而中断等等...很快Dean推出一个"updated version"。
要做到最好真的好辛苦。
目前似乎Dean的最终版本是最全面的解决方案。不过就我个人意见,感觉有些吹毛求疵了。尽量使用浏览器本身的实现和保持简单是我一贯坚持的主张。但洋人这种严谨的态度,还是让我深深敬佩。
var x = document.getElementsByTagName(’H3’);
for (var i=0;i<x.length;i++)
{
x[i].onclick = openClose;
x[i].relatedElement = x[i].nextSibling; // simplified situation
x[i].relatedElement.relatedElement = x[i];
}
}或者在函数中使用脚本语言最常见的闭句Closures的时候,IE都无法回收内存。而闭句在给DOM对象注册事件处理器(event handler)的时候最为常用。Novemberborn提供了一些example可以让你运行并切实感受到这个bug。
我最喜爱的QuirkMode 去年初意识到这个bug存在巨大隐患,觉得有必要呼吁广大web开发者关注并竭力避免这个问题,于是举办了一个慈善邀请赛,鼓励大家提交各自addEvent/removeEvent 方案。并终于在去年10月下旬宣布了他们认为的胜利者:John Resig,让 John赢得胜利的代码如下:
function addEvent( obj, type, fn ) {
if ( obj.attachEvent ) {
obj[’e’+type+fn] = fn;
obj[type+fn] = function(){obj[’e’+type+fn]( window.event );}
obj.attachEvent( ’on’+type, obj[type+fn] );
} else
obj.addEventListener( type, fn, false );
}
function removeEvent( obj, type, fn ) {
if ( obj.detachEvent ) {
obj.detachEvent( ’on’+type, obj[type+fn] );
obj[type+fn] = null;
} else
obj.removeEventListener( type, fn, false );
}
QuirkMode 对选择John为胜利者的解释概括来说就是以上代码最简洁有效,在避免内存问题的同时还巧妙的保证了this关键字在ie的attachEvent中能正常工作。缺点当然还是存在:
不支持 Netscape 4 和 Explorer 5 Mac。(有可能国内的程序员会嗤之以鼻,但国外很强调广泛的兼容性)
在 removeEvent 中遗漏了remove obj["e"+type+fn]。
总之不管怎么说,简单取胜。
结果一出,众多参赛与评论者不服气,很快又挑出了John的代码的几处毛病:
addEvent中本身就使用了闭句,所以没有根本解决IE内存泄露的问题。
没有解决同类型的事件可能被重复注册而被IE重复执行的问题。
几个高手于是提出了改进性的方案: /*
Original idea by John Resig
Tweaked by Scott Andrew LePera, Dean Edwards and Peter-Paul Koch
Fixed for IE by Tino Zijdel (crisp)
Note that in IE this will cause memory leaks and still doesn’t quite function the same as in browsers that do support the W3C event model:
- event execution order is not the same (LIFO in IE against FIFO)
- functions attached to the same event on the same element multiple times will also get executed multiple times in IE
*/
function addEvent( obj, type, fn ) {
if (obj.addEventListener)
obj.addEventListener( type, fn, false );
else if (obj.attachEvent) {
obj["e"+type+fn] = fn;
obj.attachEvent( "on"+type, function() { obj["e"+type+fn](); } );
}
}
function removeEvent( obj, type, fn ) {
if (obj.removeEventListener)
obj.removeEventListener( type, fn, false );
else if (obj.detachEvent) {
obj.detachEvent( "on"+type, obj["e"+type+fn] );
obj["e"+type+fn] = null;
}
}
很明显,虽然修正了John代码的一些不足。但内存泄露依然存在,部分浏览器依然不支持,还是无法避免ie重复注册。另外根据注释:当在同一个对象上注册多个事件处理器的时候,IE与其他浏览器的执行顺序是不同的,这又是一个隐患。
几天之后,一个被认为最严谨的方案由Dean Edwards 提出。Dean他的方案与众不同:
不执行对象检测(Object detection)
没有调用 addeventListener/attachEvent 方法
保持this关键字的运行于正确的上下文环境
正确传递 event 对象参数
完全跨浏览器至此(包括IE4和NS4)
不存在内存泄露
Dean的代码如下: // written by Dean Edwards, 2005
// http://dean.edwards.name/function ;addEvent(element, type, handler) {
// assign each event handler a unique ID
// 为事件处理函数设定一个唯一值
if (!handler.$$guid) handler.$$guid = addEvent.guid++;
// create a hash table of event types for the element
if (!element.events) element.events = {};
// create a hash table of event handlers for each element/event pair
var handlers = element.events[type];
if (!handlers) {
handlers = element.events[type] = {};
// store the existing event handler (if there is one)
// 如果对象已经注册有事件处理,那么要保留下来,并保存为第一个
if (element["on" + type]) {
handlers[0] = element["on" + type];
}
}
// store the event handler in the hash table
handlers[handler.$$guid] = handler;
// assign a global event handler to do all the work
// 指派一个全局函数做统一的事件处理,同时避免了反复注册
element["on" + type] = handleEvent;
};
// a counter used to create unique IDs
addEvent.guid = 1;function removeEvent(element, type, handler) {
// delete the event handler from the hash table
if (element.events && element.events[type]) {
delete element.events[type][handler.$$guid];
}
};function handleEvent(event) {
// grab the event object (IE uses a global event object)
event = event || window.event;
// get a reference to the hash table of event handlers
// 这里的 this 随 handlerEvent function 被触发的source element 变化而变化
var handlers = this.events[event.type];
// execute each event handler
for (var i in handlers) {
//这样写才能保证注册的事件处理函数中的 this 得到正确的引用,直接handlers[i]()是不行的
this.$$handleEvent = handlers[i];
this.$$handleEvent(event);
}
};
这段代码相比之前就大了不少了,不过确实很精妙。可是这段代码却引入了其他的问题,比如无法处理事件处理函数的返回值,for..in循环可能因为(Object.prototype)的错误应用而中断等等...很快Dean推出一个"updated version"。
要做到最好真的好辛苦。
目前似乎Dean的最终版本是最全面的解决方案。不过就我个人意见,感觉有些吹毛求疵了。尽量使用浏览器本身的实现和保持简单是我一贯坚持的主张。但洋人这种严谨的态度,还是让我深深敬佩。
发表评论
-
javascript 键盘事件大全(兼容性研究)
2010-08-05 10:22 2406转载 javascript 键盘事 ... -
JavaScript Base64编码和解码,实现URL参数传递。
2009-12-16 13:09 1614为什么需要对参数进行编码?相信有过开发的经验的广大程序员都知道 ... -
JavaScript处理xmlhttprequest返回的xml文档
2009-12-03 17:02 2048<script type="text/java ... -
认识hasLayout——IE浏览器css bug的一大罪恶根源
2009-11-09 10:36 1801什么是hasLayout?hasLayout ... -
Javascript 文件操作 Javascript File 对象
2009-11-06 17:14 5452一、功能实现核心:FileSystemObject 对象 ... -
js 中执行swf中的方法
2009-10-26 11:05 1139注意:本方法在as3中测试可行,在as2未测试。 funct ... -
前台js encodeURIComponent编码 后台java对中文解码方法
2009-10-24 09:21 4009new String(request.getParameter ... -
js 三种编解码方式
2009-10-24 09:20 930js对文字进行编码涉及3个函数:escape,encodeUR ... -
发布一个史上最简单代码最少Javascript Timer,解决一切定时执行的问题
2009-10-20 13:34 1350function TimerStart(func,delay) ... -
JS里setTimeout为0的小应用
2009-10-19 23:02 1864在示例B中,虽然setTimeout设置为0,但是,从Java ... -
js call apply
2009-10-19 15:21 1026Function.prototype.apply = func ... -
如何向回调函数中传入其他参数
2009-10-19 13:58 1954最近写JS经常会因为向回调函数中传参而头疼,今天总结一下向回 ... -
客户端上传工具-SWFUpload
2009-10-14 10:28 2358最近由于项目中多文件上传的需求,我才发现SWFUpload已经 ... -
ie ff下Clipboard的读写js脚本
2009-09-28 15:37 2793//Firefox下Clipboard的读写js脚本 /*** ... -
jQuery对象之间的继承关系
2009-09-21 10:48 2472主要也就是jQuery,jQuery.fn和jQuery.fn ... -
jQuery选择的工作原理和优化
2009-09-21 10:39 990至于有那些选择器,在帮助手册中都有,自己去看,这篇主要是分析他 ... -
键盘KeyCode值列表
2009-09-18 17:47 945keycode 0 = keycode 1 = key ... -
仿网易163的在线HTML编辑器及其轻量化结构
2009-09-15 14:13 2688网上有些免费的在线HTML编辑器,有的功能实在是过于强大但显得 ... -
javascript图片浏览器的核心:图片预加载
2009-09-10 22:45 1771来源:热爱斯诺克的程序员 - 博客园 网站开发时经常需要 ... -
网站前端优化一些小经验
2009-08-26 16:23 842先说说目标,前端优化的 ...
相关推荐
更新时间:2015-08-31 18:00 Discourse已将站点设置添加到核心以启用“注销”菜单项。 只需在管理员设置中搜索“注销”即可启用它。话语注销菜单项该插件将注销选项添加到Discourse的用户菜单中。安装按照使用作为...
前端代码(HTML、CSS和JavaScript): ...数据管理:处理与用户、产品和订单相关的数据操作,如查询、添加、编辑和删除数据。 权限控制:确保只有经过授权的用户才能访问特定的功能和数据,防止未授权访问。
socket.io事件 接口 获取二维码url 微信登入 微信登入流程图 退出登入接口 上传用户头像接口,注意把服务器端口改为443 校验登入状态 修改用户密码接口 获取所有用户 添加用户(new) 修改用户信息 用户注册接口(废弃,...
vue-global-events通过在任何地方监听文档中的事件来添加快捷方式。赞助商Bronze安装npm install vue-global-events演示想法vue-global-events通过在任何地方监听文档中的事件来添加快捷方式。 -global-events演示...
14.5 系统主页面与动态菜单 421 14.6 用户管理模块 427 14.7 角色管理模块 439 14.8 产品管理模块 447 14.9 进仓管理模块 450 14.10 出仓管理模块 460 14.11 库存统计模块 474 14.12 用户修改密码窗口 479 14.13 ...
在线论坛包括以下功能:查看帖子信息,发表主题信息、回复主题信息、用户注册登录、管理员登录、添加主题分类、删除主题和回复信息、注销。
主要技术实现:spring、 springmvc、 springboot、mybatis 、session、 jquery 、 md5 、bootstarp.js tomcat、拦截器等。 具体主要功能模块如下: 1.用户模块管理:用户登录、用户注册、用户的查询、添加、删除...
在$ rootScope上广播“登录”,“注销”和“身份验证失败”事件,以允许应用程序的所有部分响应身份验证事件 登录后,提供了一个$ http拦截器,可将Authorization http标头添加到所有请求中 将用户名和身份验证凭据...
21、JS与页面刷新、关闭事件 257 22、SHOWMODALDIALOG和SHOWMODELESSDIALOG及其右下角提示框 257 23、特殊字体样式 258 24、JS确认窗口和输入窗口 259 25、WINDOW.SETTIMEOUT和SETINTERVAL 260 25、WINDOW.OPEN 261 ...
时间追踪器 指数 键 :chequered_flag: : 进行中 :cross_mark: : 尚未完成 :check_mark_button: :完成 计划 用户申请 :chequered_flag: 处理用户 :chequered_flag: 利用JWT和bcryptjs :check_mark_button: ...
通过随时随地收听文档中的事件来添加快捷方式 这是Vue 2的版本,如果您正在寻找Vue 3的版本, 赞助商 青铜 安装 npm install vue-global-events 理念 由于Vue的事件修饰符,处理事件非常容易,但是,您仅限于DOM...
数组方法,date对象,bom,dom以及事件等的相关知识笔记。。。。。自己看视频总结的,特别基础的部分,初级JS。
酒店管理员主要负责酒店的管理,业务功能包括:登录、注销、客房管理(查询房间、添加房间、房间概览)、订房的业务办理(房间预订、房间续费、房间退订)、订单管理(预订订单、入住订单、续费订单、历史订单、所有订单)...
OWA Keepalive 一个浏览器扩展程序,可防止从Outlook Web Applications(OWA)连续烦人地注销。安装直接来自Chrome商店前往点击添加到Chrome 转到您的Outlook网站,然后按扩展程序图标(该图标应变为红色) 当您在...
REST-服务 ... 用户可以注册、登录、查看他们的书签、添加和删除书签以及注销。 该应用程序应作为 JavaScript 中的客户端 Web 应用程序实现,其中包含由 AJAX 调用并返回 JSON 对象的服务器端 REST 服务。
快速列表(GNOME Shell扩展) ,可将动态快捷列表添加到应用程序图标的菜单中: 文件管理器书签(用于Nautilus,Nemo,Caja或Thunar) 应用程序可打开的最近文件警告:这与Dash-To-Dock或Ubuntu-Dock缩略图预览不...
Javascript小技巧一箩筐 事件源对象 event.srcElement.tagName event.srcElement.type 捕获释放 event.srcElement.setCapture(); event.srcElement.releaseCapture(); 事件按键 event.keyCode ...
15.3.8 用户动态添加记录 249 15.3.9 用户动态更新记录 251 15.3.10 用户动态删除记录 253 15.4 使用PHP获取MySQL数据库的信息 255 15.4.1 获取数据库的信息 255 15.4.2 获取表的信息 256 15.4.3 获取列的数目 256 ...