jQuery的html
方法试图通过删除调用.html('')
后作为结果被删除的任何元素的事件处理程序来预防内存泄漏。
来自1.4.2版本的源代码。
html: function( value ) {
if ( value === undefined ) {
return this[0] && this[0].nodeType === 1 ?
this[0].innerHTML.replace(rinlinejQuery, "") :
null;
}
else if ( typeof value === "string" && !rnocache.test( value ) &&
(jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
!wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
value = value.replace(rxhtmlTag, fcloseTag);
try {
for ( var i = 0, l = this.length; i < l; i++ ) {
if ( this[i].nodeType === 1 ) {
jQuery.cleanData( this[i].getElementsByTagName("*") );
this[i].innerHTML = value;
}
}
}
catch(e) {
this.empty().append( value );
}
}
else if ( jQuery.isFunction( value ) ) {
this.each(function(i){
var self = jQuery(this), old = self.html();
self.empty().append(function(){
return value.call( this, i, old );
});
});
}
else {
this.empty().append( value );
}
return this;
}
我们可以看到调用了jQuery.cleanData()
函数。以下是该函数的源代码
cleanData: function( elems ) {
var data, id, cache = jQuery.cache,
special = jQuery.event.special,
deleteExpando = jQuery.support.deleteExpando;
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
id = elem[ jQuery.expando ];
if ( id ) {
data = cache[ id ];
if ( data.events ) {
for ( var type in data.events ) {
if ( special[ type ] ) {
jQuery.event.remove( elem, type );
} else {
removeEvent( elem, type, data.handle );
}
}
}
if ( deleteExpando ) {
delete elem[ jQuery.expando ];
} else if ( elem.removeAttribute ) {
elem.removeAttribute( jQuery.expando );
}
delete cache[ id ];
}
}
}
这会在
jQuery.cache
对象中查找与每个将被调用
.html('')
删除的元素相关联的数据对象的事件对象属性中的任何事件类型属性,并将其移除。
简单来说,当使用jQuery将函数绑定为元素上引发事件的处理程序时,会将一个数据对象添加为
jQuery.cache
对象的属性。此数据对象包含一个events属性对象,该对象将创建一个属性,该属性的名称与要绑定事件处理程序函数的事件类型匹配。这个属性将包含一个应在元素上引发事件时调用的函数数组,所以事件处理程序函数将添加到此数组中。如果这是问题中首个事件类型和元素的事件处理程序函数,则使用
addEventListener/attachEvent
将注册带有调用apply的
jQuery.event.handle
函数(使用元素作为上下文,使得在函数执行上下文中的
this
将指向元素)。
当引发事件时,
jQuery.event.handle
函数将调用与事件类型和引发事件的元素匹配的数据对象的events属性对象中数组上的所有函数。
因此,总结一下,
html('')
不应该导致内存泄漏,因为有多重防御措施可防止它们的发生。
window.onunload
以移除事件处理程序。你可以在1.4.2源代码中,在Sizzle代码块之前找到相关的代码 - http://code.jquery.com/jquery-1.4.2.js :) - Russ Cam