彩世界开奖app官网-彩世界平台官方网址(彩票平台)
做最好的网站
来自 彩世界平台官方网址 2019-11-28 06:03 的文章
当前位置: 彩世界开奖app官网 > 彩世界平台官方网址 > 正文

最佳的addEvent事件绑定是怎样诞生的【彩世界平台

在日前介绍的通过绑定函数注册事件是为成分对象创立了一个事变的hash对象用来保存事件管理程序,这些hash对象在要素移除事件管理程序的时候起到了老大总要左右,根据她就会确切的移除对应的事件管理程序。移除事件管理程序的代码如下: 复制代码 代码如下: function removeHandler (obj, type, handler, scope) { obj.eventHash = obj.eventHash || {}; var evtList = obj.eventHash [type] || [], len = evtList.length; if { for { var curEvtObj = evtList[len]; if (curEvtObj.name == type && curEvtObj.handler === handler && curEvtObj.scope === scope) { if (obj.removeEventListener) { obj.removeEventListener(type, curEvtObj.fn, false); } else if { obj.detachEvent("on" type, curEvtObj.fn); } else { obj["on" type] = null; } evtList.splice; break; } } } } 到此处就介绍完了应用函数绑定本领注册特定施行情状的事件管理程序。雷同,利用函数绑定还可以使回调函数在加以的施行景况之中实施。 本文版权归我和天涯论坛共有,应接转发,但未经小编同意必得保留此段表明,且在文章页面显然地点给出原作连接,不然保留深究法律义务的权利。

当前有如Dean的最后版本是最完备的消除方案。可是就自己个人观点,感到微微洗垢求瘢了。尽量利用浏览器本人的兑现和保全轻松是本人定位坚威武不能屈的看好。但法国人这种小心翼翼的情态,依旧让自家深入佩泰山压顶不弯腰。

实行上边这段代码,管理程序eventHandler的this成效域就处在了window对象下边。

很显著,固然改善了John代码的有个别欠缺。但内部存款和储蓄器败露照旧留存,部分浏览器依然不帮助,依然不或者幸免ie重复注册。别的依照注释:当在同二个目的上登记多个事件微电脑的时候,IE与任何浏览器的进行顺序是区别的,那又是七个隐患。

透过以上3种格局为input成分注册一个 click 事件管理程序都有贰个欠缺正是这几个处理程序的作用域始终处在input对象。在面向对象编制程序的时候,就要求显著的钦命this在一定的成效域下边。 为了改动this的功效域,就得用到js的风度翩翩种绑定函数技艺。 所谓“绑定函数”正是要开创多少个函数,能够在一定条件中以指定参数调用另一个函数,他能很好的与事件管理程序一齐利用,以便在将函数作为变量传递的同一时间保险函数的成效域。绑定函数的定义情势如下代码: 复制代码 代码如下: function bind { return fn.apply(scope||this,arguments); } 那么些绑定函数选拔五个参数,第叁个是内需实行的函数,首个是一定的进行遭遇,并回到贰个在给定功能域中调用给定函数,并将持有参数一齐传递过去。利用绑定函数本事和DOM2级的事件管理程序就能够很好的为要素注册一个在一定功用域下实行的事件管理函数。具体的管理格局如下: 首先更改先前定义的挂号事件的主意如下代码: 复制代码 代码如下: function addHandler(obj, type, handler, scope) { function fn { var evt = event ? event : window.event; evt.target = event.target || event.srcElement; return handler.apply(scope || this,arguments); } obj.eventHash = obj.eventHash || {};//这里为急需注册事件管理程序的对象定义一个封存事件的hash对象,并把事件管理程序和成效域保存在该事件类型的行列之中 (obj.eventHash [type] = obj.eventHash [type] || []).push({ "name": type, "handler": handler, "fn": fn, "scope": scope }); if { obj.addEventListener; } else if { obj.attachEvent; } else { obj["on" type] = fn; } } 使用改进后的注册事件措施就足以使成分的事件管理程序在钦赐的条件之中推行了。 复制代码 代码如下:

/*
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:

其二种方式,便是理由DOM2等级的事件管理方法 add伊夫ntListener和remove伊芙ntListener,针对ie浏览器对应的秘诀是attach伊芙nt 和 detachEvent。注册事件的代码如下: 复制代码 代码如下:

复制代码 代码如下:

第黄金年代种,也是 最见惯司空的,就是直接在html标签里面通过点名事件管理程序同名的HTML属性来注册事件,代码如下: 复制代码 代码如下: function eventHandler() { alert; } 第三种艺术正是将叁个函数赋值给贰个事件管理程序属性。这种艺术首先的获取到这一个因素对象,日常代码如下: 复制代码 代码如下:

几天今后,二个被以为最严格的方案由迪恩 Edwards提议。Dean他的方案非常:

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];
}
}

复制代码 代码如下:

复制代码 代码如下:

不援助 Netscape 4 和 Explorer 5 Mac。(有希望国内的工程师会不屑一顾,但国外很强调遍布的宽容性)
在 removeEvent 中疏漏了remove obj["e" type fn]。
简单来说不管怎么说,简单狂胜。
结果后生可畏出,众多参赛与争辩者不服气,异常快又挑出了John的代码的几处毛病:

// written by Dean Edwards, 2005
// ;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 随 handler伊芙nt 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);
}
};

复制代码 代码如下:

抑或在函数中动用脚本语言最普及的闭句Closures的时候,IE都没有办法儿回笼内部存款和储蓄器。而闭句在给DOM对象注册事件微电脑(event handler)的时候最佳常用。Novemberborn提供了某些example能够让你运维并切实体会到那些bug。
自家最垂怜的QuirkMode 二〇一八年终察觉到这一个bug存在庞大隐患,以为有必不可缺倡议广大web开拓者关切并用力防止这些难点,于是开设了一个慈祥国际比赛,慰勉咱们提交各自 add伊夫nt/remove伊夫nt 方案。并终于在二零一八年7月下旬发布了她们认为的胜者:JohnResig,让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 );
}

要产生最佳真适逢其时艰难。

当大家编辑脚本的时候创制了接力引用,举个例子如下代码:

  • 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;
    }
    }

复制代码 代码如下: window.onload = function () { var x = document.getElementsByTagName('H3'); for...

QuirkMode 对选用John为胜利者的讲授归纳来说正是上述代码最精练有效,在幸免内部存款和储蓄器难点的还要还抢眼的保管了this关键字在ie的attachEvent中能正常干活。劣势当然如故存在:

不进行对象检查评定(Object detection)
从未有过调用 addeventListener/attach伊芙nt 方法
保证this关键字的运作张成功确的上下文情状
是的传递 event 对象参数
全盘跨浏览器至此(包含IE4和NS4)
不设有内部存款和储蓄器败露
Dean的代码如下:

这段代码相比较早前就大了广大了,不超过实际在很精细。然则这段代码却引进了别样的题目,例如不能处总管件管理函数的重返值,for..in循环恐怕因为 (Object.prototype)的荒诞选取而搁浅等等...相当的慢迪恩推出三个"updated version"。

add伊夫nt中本人就动用了闭句,所以并未有根本化解IE内部存储器走漏的主题材料。
从不缓慢解决同类别的事件也许被再一次登记而被IE重复实施的难题。
多少个高手于是提议了更改性的方案:

本文由彩世界开奖app官网发布于彩世界平台官方网址,转载请注明出处:最佳的addEvent事件绑定是怎样诞生的【彩世界平台

关键词: 脚本 函数 绑定 之家