classes.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. define([
  2. "../core",
  3. "../var/rnotwhite",
  4. "../var/strundefined",
  5. "../data/var/data_priv",
  6. "../core/init"
  7. ], function( jQuery, rnotwhite, strundefined, data_priv ) {
  8. var rclass = /[\t\r\n\f]/g;
  9. jQuery.fn.extend({
  10. addClass: function( value ) {
  11. var classes, elem, cur, clazz, j, finalValue,
  12. proceed = typeof value === "string" && value,
  13. i = 0,
  14. len = this.length;
  15. if ( jQuery.isFunction( value ) ) {
  16. return this.each(function( j ) {
  17. jQuery( this ).addClass( value.call( this, j, this.className ) );
  18. });
  19. }
  20. if ( proceed ) {
  21. // The disjunction here is for better compressibility (see removeClass)
  22. classes = ( value || "" ).match( rnotwhite ) || [];
  23. for ( ; i < len; i++ ) {
  24. elem = this[ i ];
  25. cur = elem.nodeType === 1 && ( elem.className ?
  26. ( " " + elem.className + " " ).replace( rclass, " " ) :
  27. " "
  28. );
  29. if ( cur ) {
  30. j = 0;
  31. while ( (clazz = classes[j++]) ) {
  32. if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
  33. cur += clazz + " ";
  34. }
  35. }
  36. // only assign if different to avoid unneeded rendering.
  37. finalValue = jQuery.trim( cur );
  38. if ( elem.className !== finalValue ) {
  39. elem.className = finalValue;
  40. }
  41. }
  42. }
  43. }
  44. return this;
  45. },
  46. removeClass: function( value ) {
  47. var classes, elem, cur, clazz, j, finalValue,
  48. proceed = arguments.length === 0 || typeof value === "string" && value,
  49. i = 0,
  50. len = this.length;
  51. if ( jQuery.isFunction( value ) ) {
  52. return this.each(function( j ) {
  53. jQuery( this ).removeClass( value.call( this, j, this.className ) );
  54. });
  55. }
  56. if ( proceed ) {
  57. classes = ( value || "" ).match( rnotwhite ) || [];
  58. for ( ; i < len; i++ ) {
  59. elem = this[ i ];
  60. // This expression is here for better compressibility (see addClass)
  61. cur = elem.nodeType === 1 && ( elem.className ?
  62. ( " " + elem.className + " " ).replace( rclass, " " ) :
  63. ""
  64. );
  65. if ( cur ) {
  66. j = 0;
  67. while ( (clazz = classes[j++]) ) {
  68. // Remove *all* instances
  69. while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
  70. cur = cur.replace( " " + clazz + " ", " " );
  71. }
  72. }
  73. // Only assign if different to avoid unneeded rendering.
  74. finalValue = value ? jQuery.trim( cur ) : "";
  75. if ( elem.className !== finalValue ) {
  76. elem.className = finalValue;
  77. }
  78. }
  79. }
  80. }
  81. return this;
  82. },
  83. toggleClass: function( value, stateVal ) {
  84. var type = typeof value;
  85. if ( typeof stateVal === "boolean" && type === "string" ) {
  86. return stateVal ? this.addClass( value ) : this.removeClass( value );
  87. }
  88. if ( jQuery.isFunction( value ) ) {
  89. return this.each(function( i ) {
  90. jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
  91. });
  92. }
  93. return this.each(function() {
  94. if ( type === "string" ) {
  95. // Toggle individual class names
  96. var className,
  97. i = 0,
  98. self = jQuery( this ),
  99. classNames = value.match( rnotwhite ) || [];
  100. while ( (className = classNames[ i++ ]) ) {
  101. // Check each className given, space separated list
  102. if ( self.hasClass( className ) ) {
  103. self.removeClass( className );
  104. } else {
  105. self.addClass( className );
  106. }
  107. }
  108. // Toggle whole class name
  109. } else if ( type === strundefined || type === "boolean" ) {
  110. if ( this.className ) {
  111. // store className if set
  112. data_priv.set( this, "__className__", this.className );
  113. }
  114. // If the element has a class name or if we're passed `false`,
  115. // then remove the whole classname (if there was one, the above saved it).
  116. // Otherwise bring back whatever was previously saved (if anything),
  117. // falling back to the empty string if nothing was stored.
  118. this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
  119. }
  120. });
  121. },
  122. hasClass: function( selector ) {
  123. var className = " " + selector + " ",
  124. i = 0,
  125. l = this.length;
  126. for ( ; i < l; i++ ) {
  127. if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
  128. return true;
  129. }
  130. }
  131. return false;
  132. }
  133. });
  134. });