天天看點

深入學習jquery源碼之show()和hide()

jQueryshow([speed,[easing],[fn]])

概述:

顯示隐藏的比對元素。

這個就是 'show( speed, [callback] )' 無動畫的版本。如果選擇的元素是可見的,這個方法将不會改變任何東西。無論這個元素是通過hide()方法隐藏的還是在CSS裡設定了display:none;,這個方法都将有效。

參數:

speed[,fn] Number/String,Function

speed:三種預定速度之一的字元串("slow","normal", or "fast")或表示動畫時長的毫秒數值(如:1000)

fn:在動畫完成時執行的函數,每個元素執行一次。

[speed],[easing],[fn] Number/String,String,Function

speed:三種預定速度之一的字元串("slow","normal", or "fast")或表示動畫時長的毫秒數值(如:1000)

easing:(Optional) 用來指定切換效果,預設是"swing",可用參數"linear"

fn:在動畫完成時執行的函數,每個元素執行一次。

使用:

顯示所有段落

<p style="display: none">Hello</p>
           
$("p").show()
           

用緩慢的動畫将隐藏的段落顯示出來,曆時600毫秒。

<p style="display: none">Hello</p>
           
$("p").show("slow");
           

用迅速的動畫将隐藏的段落顯示出來,曆時200毫秒。并在之後執行回報!

<p style="display: none">Hello</p>
           
$("p").show("fast",function(){
   $(this).text("Animation Done!");
 });
           

将隐藏的段落用将近4秒的時間顯示出來。。。并在之後執行一個回報

<p style="display: none">Hello</p>
           
$("p").show(4000,function(){
   $(this).text("Animation Done...");
 });
           

jquery源碼

function showHide(elements, show) {
        var display, elem, hidden,
            values = [],
            index = 0,
            length = elements.length;

        for (; index < length; index++) {
            elem = elements[index];
            if (!elem.style) {
                continue;
            }

            values[index] = jQuery._data(elem, "olddisplay");
            display = elem.style.display;
            if (show) {
                // Reset the inline display of this element to learn if it is
                // being hidden by cascaded rules or not
                if (!values[index] && display === "none") {
                    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 (elem.style.display === "" && isHidden(elem)) {
                    values[index] = jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
                }
            } else {
                hidden = isHidden(elem);

                if (display && display !== "none" || !hidden) {
                    jQuery._data(elem, "olddisplay", hidden ? display : jQuery.css(elem, "display"));
                }
            }
        }

        // Set the display of most of the elements in a second loop
        // to avoid the constant reflow
        for (index = 0; index < length; index++) {
            elem = elements[index];
            if (!elem.style) {
                continue;
            }
            if (!show || elem.style.display === "none" || elem.style.display === "") {
                elem.style.display = show ? values[index] || "" : "none";
            }
        }

        return elements;
    }


 jQuery.fn.extend({

     show: function () {
            return showHide(this, true);
        }
});



       /**
     * Determines whether an object can have data
     */
    jQuery.acceptData = function (elem) {
        var noData = jQuery.noData[(elem.nodeName + " ").toLowerCase()],
            nodeType = +elem.nodeType || 1;

        // Do not set data on non-element DOM nodes because it will not be cleared (#8335).
        return nodeType !== 1 && nodeType !== 9 ?
            false :

            // Nodes accept data unless otherwise specified; rejection can be conditional
            !noData || noData !== true && elem.getAttribute("classid") === noData;
    };

   function internalRemoveData(elem, name, pvt) {
        if (!jQuery.acceptData(elem)) {
            return;
        }

        var thisCache, i,
            isNode = elem.nodeType,

            // See jQuery.data for more information
            cache = isNode ? jQuery.cache : elem,
            id = isNode ? elem[jQuery.expando] : jQuery.expando;

        // If there is already no cache entry for this object, there is no
        // purpose in continuing
        if (!cache[id]) {
            return;
        }

        if (name) {

            thisCache = pvt ? cache[id] : cache[id].data;

            if (thisCache) {

                // Support array or space separated string names for data keys
                if (!jQuery.isArray(name)) {

                    // try the string as a key before any manipulation
                    if (name in thisCache) {
                        name = [name];
                    } else {

                        // split the camel cased version by spaces unless a key with the spaces exists
                        name = jQuery.camelCase(name);
                        if (name in thisCache) {
                            name = [name];
                        } else {
                            name = name.split(" ");
                        }
                    }
                } else {
                    // If "name" is an array of keys...
                    // When data is initially created, via ("key", "val") signature,
                    // keys will be converted to camelCase.
                    // Since there is no way to tell _how_ a key was added, remove
                    // both plain key and camelCase key. #12786
                    // This will only penalize the array argument path.
                    name = name.concat(jQuery.map(name, jQuery.camelCase));
                }

                i = name.length;
                while (i--) {
                    delete thisCache[name[i]];
                }

                // If there is no data left in the cache, we want to continue
                // and let the cache object itself get destroyed
                if (pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache)) {
                    return;
                }
            }
        }

        // See jQuery.data for more information
        if (!pvt) {
            delete cache[id].data;

            // Don't destroy the parent cache unless the internal data object
            // had been the only thing left in it
            if (!isEmptyDataObject(cache[id])) {
                return;
            }
        }

        // Destroy the cache
        if (isNode) {
            jQuery.cleanData([elem], true);

            // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
            /* jshint eqeqeq: false */
        } else if (support.deleteExpando || cache != cache.window) {
            /* jshint eqeqeq: true */
            delete cache[id];

            // When all else fails, null
        } else {
            cache[id] = null;
        }
    }

    jQuery.extend({
        cache: {},

        // The following elements (space-suffixed to avoid Object.prototype collisions)
        // throw uncatchable exceptions if you attempt to set expando properties
        noData: {
            "applet ": true,
            "embed ": true,
            // ...but Flash objects (which have this classid) *can* handle expandos
            "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
        },

        hasData: function (elem) {
            elem = elem.nodeType ? jQuery.cache[elem[jQuery.expando]] : elem[jQuery.expando];
            return !!elem && !isEmptyDataObject(elem);
        },

        data: function (elem, name, data) {
            return internalData(elem, name, data);
        },

        removeData: function (elem, name) {
            return internalRemoveData(elem, name);
        },

        // For internal use only.
        _data: function (elem, name, data) {
            return internalData(elem, name, data, true);
        },

        _removeData: function (elem, name) {
            return internalRemoveData(elem, name, true);
        }
    });
           

hide([speed,[easing],[fn]])

概述:

隐藏顯示的元素

這個就是 'hide( speed, [callback] )' 的無動畫版。如果選擇的元素是隐藏的,這個方法将不會改變任何東西。

參數:

speed[,fn] Number/String,Function

speed:三種預定速度之一的字元串("slow","normal", or "fast")或表示動畫時長的毫秒數值(如:1000)

fn:在動畫完成時執行的函數,每個元素執行一次。

[speed],[easing],[fn] Number/String,String,Function

speed:三種預定速度之一的字元串("slow","normal", or "fast")或表示動畫時長的毫秒數值(如:1000)

easing:(Optional) 用來指定切換效果,預設是"swing",可用參數"linear"

fn:在動畫完成時執行的函數,每個元素執行一次。

隐藏所有段落

$("p").hide()
           

用600毫秒的時間将段落緩慢的隐藏

$("p").hide("slow");
           

用200毫秒将段落迅速隐藏,之後彈出一個對話框。

$("p").hide("fast",function(){
   alert("Animation Done.");
 });
           

jquery源碼

jQuery.fn.extend({
        hide: function () {
            return showHide(this);
        }
    });