dom-class.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. define("dojo/dom-class", ["./_base/lang", "./_base/array", "./dom"], function(lang, array, dom){
  2. // module:
  3. // dojo/dom-class
  4. // summary:
  5. // This module defines the core dojo DOM class API.
  6. var className = "className";
  7. /* Part I of classList-based implementation is preserved here for posterity
  8. var classList = "classList";
  9. has.add("dom-classList", function(){
  10. return classList in document.createElement("p");
  11. });
  12. */
  13. // =============================
  14. // (CSS) Class Functions
  15. // =============================
  16. /*=====
  17. dojo.hasClass = function(node, classStr){
  18. // summary:
  19. // Returns whether or not the specified classes are a portion of the
  20. // class list currently applied to the node.
  21. //
  22. // node: String|DOMNode
  23. // String ID or DomNode reference to check the class for.
  24. //
  25. // classStr: String
  26. // A string class name to look for.
  27. //
  28. // returns: Boolean
  29. //
  30. // example:
  31. // Do something if a node with id="someNode" has class="aSillyClassName" present
  32. // | if(dojo.hasClass("someNode","aSillyClassName")){ ... }
  33. };
  34. =====*/
  35. /*=====
  36. dojo.addClass = function(node, classStr){
  37. // summary:
  38. // Adds the specified classes to the end of the class list on the
  39. // passed node. Will not re-apply duplicate classes.
  40. //
  41. // node: String|DOMNode
  42. // String ID or DomNode reference to add a class string too
  43. //
  44. // classStr: String|Array
  45. // A String class name to add, or several space-separated class names,
  46. // or an array of class names.
  47. //
  48. // example:
  49. // Add a class to some node:
  50. // | dojo.addClass("someNode", "anewClass");
  51. //
  52. // example:
  53. // Add two classes at once:
  54. // | dojo.addClass("someNode", "firstClass secondClass");
  55. //
  56. // example:
  57. // Add two classes at once (using array):
  58. // | dojo.addClass("someNode", ["firstClass", "secondClass"]);
  59. //
  60. // example:
  61. // Available in `dojo.NodeList` for multiple additions
  62. // | dojo.query("ul > li").addClass("firstLevel");
  63. };
  64. =====*/
  65. /*=====
  66. dojo.removeClass = function(node, classStr){
  67. // summary:
  68. // Removes the specified classes from node. No `dojo.hasClass`
  69. // check is required.
  70. //
  71. // node: String|DOMNode
  72. // String ID or DomNode reference to remove the class from.
  73. //
  74. // classStr: String|Array
  75. // An optional String class name to remove, or several space-separated
  76. // class names, or an array of class names. If omitted, all class names
  77. // will be deleted.
  78. //
  79. // example:
  80. // Remove a class from some node:
  81. // | dojo.removeClass("someNode", "firstClass");
  82. //
  83. // example:
  84. // Remove two classes from some node:
  85. // | dojo.removeClass("someNode", "firstClass secondClass");
  86. //
  87. // example:
  88. // Remove two classes from some node (using array):
  89. // | dojo.removeClass("someNode", ["firstClass", "secondClass"]);
  90. //
  91. // example:
  92. // Remove all classes from some node:
  93. // | dojo.removeClass("someNode");
  94. //
  95. // example:
  96. // Available in `dojo.NodeList()` for multiple removal
  97. // | dojo.query(".foo").removeClass("foo");
  98. };
  99. =====*/
  100. /*=====
  101. dojo.replaceClass = function(node, addClassStr, removeClassStr){
  102. // summary:
  103. // Replaces one or more classes on a node if not present.
  104. // Operates more quickly than calling dojo.removeClass and dojo.addClass
  105. //
  106. // node: String|DOMNode
  107. // String ID or DomNode reference to remove the class from.
  108. //
  109. // addClassStr: String|Array
  110. // A String class name to add, or several space-separated class names,
  111. // or an array of class names.
  112. //
  113. // removeClassStr: String|Array?
  114. // A String class name to remove, or several space-separated class names,
  115. // or an array of class names.
  116. //
  117. // example:
  118. // | dojo.replaceClass("someNode", "add1 add2", "remove1 remove2");
  119. //
  120. // example:
  121. // Replace all classes with addMe
  122. // | dojo.replaceClass("someNode", "addMe");
  123. //
  124. // example:
  125. // Available in `dojo.NodeList()` for multiple toggles
  126. // | dojo.query(".findMe").replaceClass("addMe", "removeMe");
  127. };
  128. =====*/
  129. /*=====
  130. dojo.toggleClass = function(node, classStr, condition){
  131. // summary:
  132. // Adds a class to node if not present, or removes if present.
  133. // Pass a boolean condition if you want to explicitly add or remove.
  134. // Returns the condition that was specified directly or indirectly.
  135. //
  136. // node: String|DOMNode
  137. // String ID or DomNode reference to toggle a class string
  138. //
  139. // classStr: String|Array
  140. // A String class name to toggle, or several space-separated class names,
  141. // or an array of class names.
  142. //
  143. // condition:
  144. // If passed, true means to add the class, false means to remove.
  145. // Otherwise dojo.hasClass(node, classStr) is used to detect the class presence.
  146. //
  147. // example:
  148. // | dojo.toggleClass("someNode", "hovered");
  149. //
  150. // example:
  151. // Forcefully add a class
  152. // | dojo.toggleClass("someNode", "hovered", true);
  153. //
  154. // example:
  155. // Available in `dojo.NodeList()` for multiple toggles
  156. // | dojo.query(".toggleMe").toggleClass("toggleMe");
  157. };
  158. =====*/
  159. var cls, // exports object
  160. spaces = /\s+/, a1 = [""];
  161. function str2array(s){
  162. if(typeof s == "string" || s instanceof String){
  163. if(s && !spaces.test(s)){
  164. a1[0] = s;
  165. return a1;
  166. }
  167. var a = s.split(spaces);
  168. if(a.length && !a[0]){
  169. a.shift();
  170. }
  171. if(a.length && !a[a.length - 1]){
  172. a.pop();
  173. }
  174. return a;
  175. }
  176. // assumed to be an array
  177. if(!s){
  178. return [];
  179. }
  180. return array.filter(s, function(x){ return x; });
  181. }
  182. /* Part II of classList-based implementation is preserved here for posterity
  183. if(has("dom-classList")){
  184. // new classList version
  185. cls = {
  186. contains: function containsClass(node, classStr){
  187. var clslst = classStr && dom.byId(node)[classList];
  188. return clslst && clslst.contains(classStr); // Boolean
  189. },
  190. add: function addClass(node, classStr){
  191. node = dom.byId(node);
  192. classStr = str2array(classStr);
  193. for(var i = 0, len = classStr.length; i < len; ++i){
  194. node[classList].add(classStr[i]);
  195. }
  196. },
  197. remove: function removeClass(node, classStr){
  198. node = dom.byId(node);
  199. if(classStr === undefined){
  200. node[className] = "";
  201. }else{
  202. classStr = str2array(classStr);
  203. for(var i = 0, len = classStr.length; i < len; ++i){
  204. node[classList].remove(classStr[i]);
  205. }
  206. }
  207. },
  208. replace: function replaceClass(node, addClassStr, removeClassStr){
  209. node = dom.byId(node);
  210. if(removeClassStr === undefined){
  211. node[className] = "";
  212. }else{
  213. removeClassStr = str2array(removeClassStr);
  214. for(var i = 0, len = removeClassStr.length; i < len; ++i){
  215. node[classList].remove(removeClassStr[i]);
  216. }
  217. }
  218. addClassStr = str2array(addClassStr);
  219. for(i = 0, len = addClassStr.length; i < len; ++i){
  220. node[classList].add(addClassStr[i]);
  221. }
  222. },
  223. toggle: function toggleClass(node, classStr, condition){
  224. node = dom.byId(node);
  225. if(condition === undefined){
  226. classStr = str2array(classStr);
  227. for(var i = 0, len = classStr.length; i < len; ++i){
  228. node[classList].toggle(classStr[i]);
  229. }
  230. }else{
  231. cls[condition ? "add" : "remove"](node, classStr);
  232. }
  233. return condition; // Boolean
  234. }
  235. }
  236. }
  237. */
  238. // regular DOM version
  239. var fakeNode = {}; // for effective replacement
  240. cls = {
  241. contains: function containsClass(/*DomNode|String*/node, /*String*/classStr){
  242. return ((" " + dom.byId(node)[className] + " ").indexOf(" " + classStr + " ") >= 0); // Boolean
  243. },
  244. add: function addClass(/*DomNode|String*/node, /*String|Array*/classStr){
  245. node = dom.byId(node);
  246. classStr = str2array(classStr);
  247. var cls = node[className], oldLen;
  248. cls = cls ? " " + cls + " " : " ";
  249. oldLen = cls.length;
  250. for(var i = 0, len = classStr.length, c; i < len; ++i){
  251. c = classStr[i];
  252. if(c && cls.indexOf(" " + c + " ") < 0){
  253. cls += c + " ";
  254. }
  255. }
  256. if(oldLen < cls.length){
  257. node[className] = cls.substr(1, cls.length - 2);
  258. }
  259. },
  260. remove: function removeClass(/*DomNode|String*/node, /*String|Array?*/classStr){
  261. node = dom.byId(node);
  262. var cls;
  263. if(classStr !== undefined){
  264. classStr = str2array(classStr);
  265. cls = " " + node[className] + " ";
  266. for(var i = 0, len = classStr.length; i < len; ++i){
  267. cls = cls.replace(" " + classStr[i] + " ", " ");
  268. }
  269. cls = lang.trim(cls);
  270. }else{
  271. cls = "";
  272. }
  273. if(node[className] != cls){ node[className] = cls; }
  274. },
  275. replace: function replaceClass(/*DomNode|String*/node, /*String|Array*/addClassStr, /*String|Array?*/removeClassStr){
  276. node = dom.byId(node);
  277. fakeNode[className] = node[className];
  278. cls.remove(fakeNode, removeClassStr);
  279. cls.add(fakeNode, addClassStr);
  280. if(node[className] !== fakeNode[className]){
  281. node[className] = fakeNode[className];
  282. }
  283. },
  284. toggle: function toggleClass(/*DomNode|String*/node, /*String|Array*/classStr, /*Boolean?*/condition){
  285. node = dom.byId(node);
  286. if(condition === undefined){
  287. classStr = str2array(classStr);
  288. for(var i = 0, len = classStr.length, c; i < len; ++i){
  289. c = classStr[i];
  290. cls[cls.contains(node, c) ? "remove" : "add"](node, c);
  291. }
  292. }else{
  293. cls[condition ? "add" : "remove"](node, classStr);
  294. }
  295. return condition; // Boolean
  296. }
  297. };
  298. return cls;
  299. });