五、数据缓存Data4——jQuery.cleanData(elems)

// 代码行:5843——5875
    // 方法jQuery.cleanData(elems)用于移除多个DOM元素关联得全部数据和事件,尽在jQuery内部使用。当通过jquery方法移除DOM元素时,jQuery必须确保关联的数据和事件也被移除,以避免内存泄漏。
    cleanData: function( elems ) {
        // 参数elems是待移除数据和事件得DOM元素数组
        var data, elem, type,
        // jQuery.event.special是特殊事件修正对象得集合
            special = jQuery.event.special,
            i = 0;

            // 把elems[i]赋值给elem,并检测是否为undefined
        for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
            if ( acceptData( elem ) ) {
                if ( ( data = elem[ dataPriv.expando ] ) ) {
                    // 如果DOM元素关联得数据缓存对象含有属性events,说明在该元素上(他Jon该国jQuery事件方法)绑定过事件,则移除该元素上绑定得所有类型得事件
                    if ( data.events ) {
                        // 属性data.events是该DOM元素得事件缓存对象,存储了该DOM元素得所有事件;属性data.handle是该DOM元素得主监听函数,是该DOM元素上所有事件响应得统一入口。
                        // 如果某个事件需要特殊得移除行为,则需要调用方法jQuery.event.remove( elem, type )移除属性events中得所有事件监听函数和主事件监听函数data.handle,并删除数据缓存对象data.events;否则可以执行jQuery.removeEvent()直接移除主事件监听函数data.handle,
                        for ( type in data.events ) {
                            if ( special[ type ] ) {
                                jQuery.event.remove( elem, type );

                            // This is a shortcut to avoid jQuery.event.remove's overhead
                            } else {
                                jQuery.removeEvent( elem, type, data.handle );
                            }
                        }
                    }

                    // Support: Chrome <=35 - 45+
                    // Assign undefined instead of using delete, see Data#remove
                    elem[ dataPriv.expando ] = undefined;
                }
                // 移除DOM元素上扩展得jQuery.expando属性
                if ( elem[ dataUser.expando ] ) {

                    // Support: Chrome <=35 - 45+
                    // Assign undefined instead of using delete, see Data#remove
                    elem[ dataUser.expando ] = undefined;
                }
            }
        }
    }

// 代码行:5933——5944
    // 方法.empty()在移除匹配元素得所有子元素之前,会先调用方法jQuery.cleanData()移除所有子元素关联得数据和事件。
    empty: function() {
        var elem,
            i = 0;

        for ( ; ( elem = this[ i ] ) != null; i++ ) {
            if ( elem.nodeType === 1 ) {

                // Prevent memory leaks
                jQuery.cleanData( getAll( elem, false ) );

                // Remove any remaining nodes
                elem.textContent = "";
            }
        }

        return this;
    },

// 代码行:5960——5997
    // .html(value)返回或设置HTML内容,通过调用access()方法实现。在设置属性innerHTML之前,会先调用方法jQuery.cleanData(elems)移除所有子元素关联的数据和事件。
    html: function( value ) {
        return access( this, function( value ) {
            var elem = this[ 0 ] || {},
                i = 0,
                l = this.length;

            if ( value === undefined && elem.nodeType === 1 ) {
                return elem.innerHTML;
            }

            // See if we can take a shortcut and just use innerHTML
            if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
                !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {

                value = jQuery.htmlPrefilter( value );

                try {
                    for ( ; i < l; i++ ) {
                        elem = this[ i ] || {};

                        // Remove element nodes and prevent memory leaks
                        if ( elem.nodeType === 1 ) {
                            jQuery.cleanData( getAll( elem, false ) );
                            elem.innerHTML = value;
                        }
                    }

                    elem = 0;

                // If using innerHTML throws an exception, use the fallback method
                } catch ( e ) {}
            }

            if ( elem ) {
                this.empty().append( value );
            }
        }, null, value, arguments.length );
    },

 

posted @ 2019-05-31 10:30  道鼎金刚  阅读(436)  评论(0)    收藏  举报