现在的位置: 首页 > 综合 > 正文

jQuery源码分析16: .hide()与.show()

2019年10月29日 ⁄ 综合 ⁄ 共 3295字 ⁄ 字号 评论关闭

jQuery源码分析16: .hide()与.show()

hide: function( speed, easing, callback ) {
    if ( speed || speed === 0 ) {   //< 当提供speed参数时使用animate动画隐藏DOM结点
        return this.animate( genFx("hide", 3), speed, easing, callback);
    } else {    //< 当不提供任何参数时,先遍历jQuery对象,缓存每一个DOM结点的display值以便调用.show()时恢复原先的display值,然后将display值设置为none
        var elem, display,
            i = 0,
            j = this.length;
 
        for ( ; i < j; i++ ) {
            elem = this[i];
            if ( elem.style ) {
                display = jQuery.css( elem, "display" );
 
                if ( display !== "none" && !jQuery._data( elem, "olddisplay" ) ) {
                    jQuery._data( elem, "olddisplay", display );
                }
            }
        }
 
        // Set the display of the elements in a second loop
        // to avoid the constant reflow
        for ( i = 0; i < j; i++ ) {
            if ( this[i].style ) {
                this[i].style.display = "none";
            }
        }
 
        return this;
    }
},

//< .show()原理与.hide()相似,.hide()中使用.data()缓存的值用于这里调用.show()里恢复
show: function( speed, easing, callback ) {
    var elem, display;
 
    if ( speed || speed === 0 ) {
        return this.animate( genFx("show", 3), speed, easing, callback );
    } else {
        for ( var i = 0, j = this.length; i < j; i++ ) {
            elem = this[ i ];
 
            if ( elem.style ) {
                display = elem.style.display;
 
                // Reset the inline display of this element to learn if it is
                // being hidden by cascaded rules or not
                if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
                    display = elem.style.display = "";
                }
 
                // Set elements which have been overridden with display: none
                // in a stylesheet to whatever the default browser style is
                // for such an element
                if ( display === "" && jQuery.css(elem, "display") === "none" ) {
                    jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
                }
            }
        }
 
        // Set the display of most of the elements in a second loop
        // to avoid the constant reflow
        for ( i = 0; i < j; i++ ) {
            elem = this[ i ];
 
            if ( elem.style ) {
                display = elem.style.display;
 
                if ( display === "" || display === "none" ) {
                    elem.style.display = jQuery._data( elem, "olddisplay" ) || "";
                }
            }
        }
 
        return this;
    }
},

其中defaultDisplay函数定义目的为获取不同元素默认的display值.
var elemdisplay = {};

// Try to restore the default display value of an element 
//< 获取不同元素默认的display值,缓存在elemdisplay中
function defaultDisplay( nodeName ) {

    if ( !elemdisplay[ nodeName ] ) {

        var body = document.body,
            elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),
            display = elem.css( "display" );
        elem.remove();

        // If the simple way fails,
        // get element's real default display by attaching it to a temp iframe
        if ( display === "none" || display === "" ) {
            // No iframe to use yet, so create it
            if ( !iframe ) {
                iframe = document.createElement( "iframe" );
                iframe.frameBorder = iframe.width = iframe.height = 0;
            }

            body.appendChild( iframe );

            // Create a cacheable copy of the iframe document on first call.
            // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
            // document to it; WebKit & Firefox won't allow reusing the iframe document.
            if ( !iframeDoc || !iframe.createElement ) {
                iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
                iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "<!doctype html>" : "" ) + "<html><body>" );
                iframeDoc.close();
            }

            elem = iframeDoc.createElement( nodeName );

            iframeDoc.body.appendChild( elem );

            display = jQuery.css( elem, "display" );
            body.removeChild( iframe );
        }

        // Store the correct default display
        elemdisplay[ nodeName ] = display;
    }

    return elemdisplay[ nodeName ];
}

抱歉!评论已关闭.