classes.js 4.2 KB

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