Ответ 1
Метод jQuery html
пытается предотвратить утечку памяти, удалив обработчики событий для любых элементов, которые были удалены в результате вызова .html('')
объекта jQuery.
Из источника 1.4.2
html: function( value ) {
if ( value === undefined ) {
return this[0] && this[0].nodeType === 1 ?
this[0].innerHTML.replace(rinlinejQuery, "") :
null;
}
// See if we can take a shortcut and just use innerHTML
// THE RELEVANT PART
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++ ) {
// Remove element nodes and prevent memory leaks
if ( this[i].nodeType === 1 ) {
jQuery.cleanData( this[i].getElementsByTagName("*") );
this[i].innerHTML = value;
}
}
// If using innerHTML throws an exception, use the fallback method
}
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
. Этот объект данных содержит объект свойств событий, который будет иметь свойство, созданное на нем, с именем, соответствующим типу события, к которому вы хотите привязать функцию обработчика события. это свойство будет содержать массив функций, который должен вызываться, когда событие возникает на элементе, поэтому функция обработчика события добавляется в этот массив. Если это первая функция обработчика события для типа события и соответствующего элемента, функция jQuery.event.handle
с вызовом применить (используя этот элемент в качестве контекста, так что this
в контексте выполнения функции будет ссылаться на элемент) регистрируется в браузере с помощью addEventListener/attachEvent
.
Когда событие возбуждено, функция jQuery.event.handle
вызывает все функции в массиве в свойстве объекта свойств событий объекта данных, соответствующего типу события и элементу, на котором было создано событие.
Таким образом, html('')
не должно вызывать утечки памяти, поскольку существует ряд защитных мер, чтобы предотвратить их.