天天看點

深入學習jquery源碼之addClass()和toggleClass()與hasClass()

深入學習jquery源碼之addClass()和toggleClass()與hasClass()

addClass(class|fn)

概述

為每個比對的元素添加指定的類名。

參數

class String

一個或多個要添加到元素中的CSS類名,請用空格分開

function(index, class) Function

此函數必須傳回一個或多個空格分隔的class名。接受兩個參數,index參數為對象在這個集合中的索引值,class參數為這個對象原先的class屬性值。

為比對的元素加上 'selected' 類

$("p").addClass("selected");
$("p").addClass("selected1 selected2");
           

給li加上不同的class

<ul>
      <li>Hello</li>
      <li>Hello</li>
      <li>Hello</li>
</ul>
           
$('ul li:last').addClass(function() {
  return 'item-' + $(this).index();
});
           

removeClass([class|fn])

概述

從所有比對的元素中删除全部或者指定的類。

參數

class String

一個或多個要删除的CSS類名,請用空格分開

function(index, class) Function

此函數必須傳回一個或多個空格分隔的class名。接受兩個參數,index參數為對象在這個集合中的索引值,class參數為這個對象原先的class屬性值。

從比對的元素中删除 'selected' 類

$("p").removeClass("selected");
           

删除比對元素的所有類

$("p").removeClass();
           

删除最後一個元素上與前面重複的class

$('li:last').removeClass(function() {
    return $(this).prev().attr('class');
});
           

toggleClass(class|fn[,sw])

概述

如果存在(不存在)就删除(添加)一個類。

參數

class String

CSS類名

class,switch String,Boolean

1:要切換的CSS類名.

2:用于決定元素是否包含class的布爾值。

switch Boolean

用于決定元素是否包含class的布爾值。

function(index, class,switch)[, switch]  Function,Boolean

1:用來傳回在比對的元素集合中的每個元素上用來切換的樣式類名的一個函數。接收元素的索引位置和元素舊的樣式類作為參數。

2: 一個用來判斷樣式類添加還是移除的 boolean 值。

為比對的元素切換 'selected' 類

$("p").toggleClass("selected");
           

每點選三下加上一次 'highlight' 類

<strong>jQuery 代碼:</strong>
           
var count = 0;
  $("p").click(function(){
      $(this).toggleClass("highlight", count++ % 3 == 0);
  });
           

根據父元素來設定class屬性

$('div.foo').toggleClass(function() {
  if ($(this).parent().is('.bar') {
    return 'happy';
  } else {
    return 'sad';
  }
});
           

hasClass(class)

概述

檢查目前的元素是否含有某個特定的類,如果有,則傳回true。

這其實就是 is("." + class)。

參數

class String

用于比對的類名

給包含有某個類的元素進行一個動畫。

<div class="protected"></div><div></div>
           
$("div").click(function(){
  if ( $(this).hasClass("protected") )
    $(this)
      .animate({ left: -10 })
      .animate({ left: 10 })
      .animate({ left: -10 })
      .animate({ left: 10 })
      .animate({ left: 0 });
});
           

jquery源碼

var rclass = /[\t\r\n\f]/g;

    jQuery.fn.extend({
        addClass: function (value) {
            var classes, elem, cur, clazz, j, finalValue,
                i = 0,
                len = this.length,
                proceed = typeof value === "string" && value;

            if (jQuery.isFunction(value)) {
                return this.each(function (j) {
                    jQuery(this).addClass(value.call(this, j, this.className));
                });
            }

            if (proceed) {
                // The disjunction here is for better compressibility (see removeClass)
                classes = (value || "").match(rnotwhite) || [];

                for (; i < len; i++) {
                    elem = this[i];
                    cur = elem.nodeType === 1 && (elem.className ?
                        (" " + elem.className + " ").replace(rclass, " ") :
                        " "
                    );

                    if (cur) {
                        j = 0;
                        while ((clazz = classes[j++])) {
                            if (cur.indexOf(" " + clazz + " ") < 0) {
                                cur += clazz + " ";
                            }
                        }

                        // only assign if different to avoid unneeded rendering.
                        finalValue = jQuery.trim(cur);
                        if (elem.className !== finalValue) {
                            elem.className = finalValue;
                        }
                    }
                }
            }

            return this;
        },

        removeClass: function (value) {
            var classes, elem, cur, clazz, j, finalValue,
                i = 0,
                len = this.length,
                proceed = arguments.length === 0 || typeof value === "string" && value;

            if (jQuery.isFunction(value)) {
                return this.each(function (j) {
                    jQuery(this).removeClass(value.call(this, j, this.className));
                });
            }
            if (proceed) {
                classes = (value || "").match(rnotwhite) || [];

                for (; i < len; i++) {
                    elem = this[i];
                    // This expression is here for better compressibility (see addClass)
                    cur = elem.nodeType === 1 && (elem.className ?
                        (" " + elem.className + " ").replace(rclass, " ") :
                        ""
                    );

                    if (cur) {
                        j = 0;
                        while ((clazz = classes[j++])) {
                            // Remove *all* instances
                            while (cur.indexOf(" " + clazz + " ") >= 0) {
                                cur = cur.replace(" " + clazz + " ", " ");
                            }
                        }

                        // only assign if different to avoid unneeded rendering.
                        finalValue = value ? jQuery.trim(cur) : "";
                        if (elem.className !== finalValue) {
                            elem.className = finalValue;
                        }
                    }
                }
            }

            return this;
        },

        toggleClass: function (value, stateVal) {
            var type = typeof value;

            if (typeof stateVal === "boolean" && type === "string") {
                return stateVal ? this.addClass(value) : this.removeClass(value);
            }

            if (jQuery.isFunction(value)) {
                return this.each(function (i) {
                    jQuery(this).toggleClass(value.call(this, i, this.className, stateVal), stateVal);
                });
            }

            return this.each(function () {
                if (type === "string") {
                    // toggle individual class names
                    var className,
                        i = 0,
                        self = jQuery(this),
                        classNames = value.match(rnotwhite) || [];

                    while ((className = classNames[i++])) {
                        // check each className given, space separated list
                        if (self.hasClass(className)) {
                            self.removeClass(className);
                        } else {
                            self.addClass(className);
                        }
                    }

                    // Toggle whole class name
                } else if (type === strundefined || type === "boolean") {
                    if (this.className) {
                        // store className if set
                        jQuery._data(this, "__className__", this.className);
                    }

                    // If the element has a class name or if we're passed "false",
                    // then remove the whole classname (if there was one, the above saved it).
                    // Otherwise bring back whatever was previously saved (if anything),
                    // falling back to the empty string if nothing was stored.
                    this.className = this.className || value === false ? "" : jQuery._data(this, "__className__") || "";
                }
            });
        },

        hasClass: function (selector) {
            var className = " " + selector + " ",
                i = 0,
                l = this.length;
            for (; i < l; i++) {
                if (this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf(className) >= 0) {
                    return true;
                }
            }

            return false;
        }
    });