我听说有人说 jQuery 使用特殊的事件库而不是浏览器提供的默认 DOM 实现。
这到底是什么意思,实际上您能提供一些例子来强调这一点吗?
最佳答案
通常,jQuery 有一个系统,其中单个处理程序附加到通过闭包保留对元素的引用的元素。
当事件在元素上发生时,它会从该元素的上下文中调用一个更通用的处理程序 (jQuery.event.handle
),该处理程序传递 event
它收到的对象。
该处理程序分析事件,通过元素的 jQuery1234567...
在 jQuery.cache
中查找元素 expando 属性,并调用也存储在该元素的 jQuery.cache
条目中的适当处理程序。
结果是唯一实际附加到元素的处理程序是 jQuery
本身创建和附加的轻量级处理程序。因此,它永远不会在 IE 中由于对 DOM 元素的任何循环引用而导致内存泄漏。
在使用 jQuery
管理事件处理程序时,您必须知道的一件事是唯一 元素与其在 jQuery.cache
中的条目之间的链接是 expando 属性。
如果您有一些代码偏离 jQuery
以从 DOM 中删除元素,则不会通知 jQuery
从 jQuery 中删除关联的处理程序和其他数据.cache
,导致它自己的内存泄漏,不限于旧版本的 IE。
因此,如果您有一段 HTML
具有通过 jQuery
附加的处理程序,并且您执行如下操作:
element_container.innerHTML = '';
...现在 jQuery.cache
中与删除的元素相关的任何条目都是孤立的,并且只要浏览器窗口保持打开状态就可能存在。
因此,如果您使用 jQuery
来管理事件绑定(bind),请务必在销毁元素时留在 API 内,以便 jQuery
可以管理和清理 jQuery。必要时缓存
。
编辑:我让处理程序翻转过来。虽然大体上是相同的概念。
/*
Here we bind 4 handlers to the same element.
*/
var elem = $('#my_elem');
// This first call to .bind() binds a generic handler to `#my_elem`.
// Then it places the handler we passed in jQuery.cache.
elem.bind( 'click', function() { alert( 'click 1' ); } );
// Generic handler already exists, so these handlers are
// just added to jQuery.cache.
elem.bind( 'click', function() { alert( 'click 2' ); } );
elem.bind( 'mouseenter', function() { alert( 'mouseenter 1' ); } );
elem.bind( 'mouseleave', function() { alert( 'mouseleave 1' ); } );
/*
This is a simplified example of the binding of the generic handler. Notice
that it actually invokes an internal function.
*/
elem[0].addEventListener( 'click', function( e ) {
_internal_handler.apply( elem, arguments );
}, false);
/*
This is a simplified example of the internal function.
*/
_internal_handler( e ) {
// Find out the type of event, like "click", or whatever
var event_type = e.type;
// Get this element's data from jQuery.cache
var data = jQuery.data( this );
// If data was found...
if( data ) {
// ...get the "events" stored in the element's data
var events = data.events;
// If events were found, and events has the current type of event...
if( events && events[ event_type ] ) {
// ...then data.events[ event_type ] will give us the Array of
// handlers for that event type, so iterate the Array,
// and fire the handlers.
for( var i = 0; i < events[ event_type ]; i++; ) {
// handler invoked
events[ event_type ][ i ].call( this, e );
}
}
}
}
这当然是代码的极端简化,但大体上显示了发生的情况。
关于javascript - jQuery DOM 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7190974/