首页 > 语言 > JavaScript > 正文

JavaScript对表格或元素按文本,数字或日期排序的方法

2024-05-06 16:20:54
字体:大 中 小
来源:转载
供稿:网友

这篇文章主要介绍了JavaScript对表格或元素按文本,数字或日期排序的方法,涉及javascript页面元素操作及排序的相关技巧,需要的朋友可以参考下

本文实例讲述了JavaScript对表格或元素按文本,数字或日期排序的方法。分享给大家供大家参考。具体实现方法如下:

 

 
  1. // Sorting table columns correctly by text, number or date. There are other  
  2. // versions, plugins, etc., for this but they either are restricted to specific  
  3. // date formats, or require EVERY row-element to be given a sort attribute; mine  
  4. // can handle many different date and number formats, and even allows for specific  
  5. // cells that may not conform to the overall date/number format for that column.  
  6. // My version also enables sorting of element hierarchies: such as a DIV containing  
  7. // P-paragraphs and SPANs - this could even be an image-gallery containing prices  
  8. // or dates within spans. Very efficient as well!! 
  9. // Example: andrew.dx.am/sortgallerydel.html 
  10. // AddSortToTables(); will make the table headers clickable, to sort columns in  
  11. // ascending or descending order, for any tables with class="sortIt". 
  12. // SortTable(tbl, col); will sort the table (tbl is an id or table object) by  
  13. // the supplied column index (indexed from 0) in ascending or descending order. 
  14. // AddSortByDate(tbl, col, dateMask); enables sorting of a column by date,  
  15. // specified by a date-mask such as 'dd-mmm-yy'. 
  16. // AddSortByNumber(tbl, col); enables sorting of a column by number. This assumes a  
  17. // period . as the decimal separator (if present); it ignores any other non-numeric  
  18. // characters. 
  19. // SortElements(parentEl, childTag, colTag, colIndex); will sort (non-table)  
  20. // elements in ascending or descending order. For example, an UL containing LIs  
  21. // and SPANs. colIndex specifies which span to sort; there may be more than one in  
  22. // the LI (0 indexed). 
  23. // Example: SortElements('divid', 'p', 'span', 2); 
  24. // 3rd span within each paragraph. 
  25. // 
  26. // AddSortByDate2(parentEl, childTag, colTag, colIndex, dateMask); and  
  27. // AddSortByNumber2(parentEl, childTag, colTag, colIndex) 
  28. // provide the same feature-set as AddSortByDate and AddSortByNumber does  
  29. // for tables, but for element hierarchies. 
  30. // If there are dates or numbers in a column (or element) which don't meet the  
  31. // date-mask or number formatting necessary to sort correctly, then these individual  
  32. // elements can be given the attribute "sort" and they will still sort correctly! 
  33. // For example, with a date column <td sort="2012/12/20"> will still sort a  
  34. // cell correctly. (This format 'YYYY/MM/DD' will be converted into a Date() object.) 
  35. var MonthNames = ["January", "February", "March", "April", "May", "June", "July",  
  36. "August", "September", "October", "November", "December"]; 
  37. var DayNames = [ "Sunday", "Monday", "Tueday", "Wednesday", "Thursday",  
  38. "Friday", "Saturday" ]; 
  39. var ShortMths = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",  
  40. "Sep", "Oct", "Nov", "Dec"]; 
  41. var ShortDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; 
  42. var AddEvent = function (elem, eventType, func) { 
  43. // Helper function. 
  44. if ( elem.addEventListener ) 
  45. AddEvent = function (elem, eventType, func) { 
  46. elem.addEventListener(eventType, func, false); 
  47. }; 
  48. else if ( elem.attachEvent ) 
  49. AddEvent = function (elem, eventType, func) { 
  50. elem.attachEvent('on' + eventType, func); 
  51. }; 
  52. else 
  53. AddEvent = function (elem, eventType, func) { 
  54. elem['on' + eventType] = func; 
  55. }; 
  56. AddEvent(elem, eventType, func); 
  57. }; 
  58. // Sort methods/algorithms attributed: 
  59. var SortTable = function (tbl, col) { 
  60. // could be called directly 
  61. SortElements(tbl, 'tr', 'td', col); 
  62. }; 
  63. var SortElements = function (parentEl, childTag, colTag, colIndex) { 
  64. // example use: SortElements('table1','tr','td',2) 
  65. // or SortElements('list1','li') 
  66. // or SortElements('divName','p','span',3) 
  67. var i, j, cTags = {}, startAt = 0, childLen, aChild, elem, 
  68. sortBy, content, elems = [], sortedLen, frag, hdrsLen, hdr; 
  69. var parent = (typeof parentEl === 'string') ?  
  70. document.getElementById(parentEl) : parentEl; 
  71. var AscText = function (a, b) { // sort() by .data as text 
  72. var x = a.data, y = b.data, 
  73. xNum = parseFloat(x), yNum = parseFloat(y); 
  74. // check if each begin with a number.. 
  75. if ( !isNaN(xNum) && !isNaN(yNum) && (xNum - yNum) ) 
  76. return xNum - yNum; 
  77. return ((x < y) ? -1 : ((x > y) ? 1 : 0)); 
  78. }; 
  79. var DescText = function (a, b) { // sort() by .data 
  80. var x = a.data, y = b.data, 
  81. xNum = parseFloat(x), yNum = parseFloat(y); 
  82. // check if each begin with a number.. 
  83. if ( !isNaN(xNum) && !isNaN(yNum) && (yNum - xNum) ) 
  84. return yNum - xNum; 
  85. return ((x > y) ? -1 : ((x < y) ? 1 : 0)); 
  86. }; 
  87. var AscNum = function (a, b) { // used with dates as well 
  88. return a.data - b.data; 
  89. }; 
  90. var DescNum = function (a, b) { 
  91. return b.data - a.data; 
  92. }; 
  93. if (parent.nodeName.toLowerCase() == 'table') { 
  94. if ( childTag == 'tr' ) { 
  95. sortBy = parent.rows[0].cells[colIndex].sortBy || 'text'; 
  96. } 
  97. parent = parent.tBodies[0] || parent; 
  98. if ( parent.rows[0].cells[0].nodeName.toLowerCase() == 'th' ) { 
  99. startAt = 1; 
  100. } 
  101. } 
  102. cTags = parent.getElementsByTagName(childTag); 
  103. if ( typeof colIndex == 'undefined' ) { 
  104. sortBy = 'text'; // sort simple lists or paragraphs as text 
  105. } 
  106. for (i = startAt, childLen = cTags.length; i < childLen; i++) { 
  107. // ..go forward examining each child 
  108. aChild = cTags[i]; 
  109. elem = (colTag) ? aChild.getElementsByTagName(colTag)[colIndex] : aChild; 
  110. if (elem) { 
  111. if ( !sortBy ) { // sorting non-table columns.. 
  112. sortBy = (typeof elem.numberValue != 'undefined') ? 'number' :  
  113. ((typeof elem.dateValue != 'undefined') ? 'date' : 'text'); 
  114. } 
  115. switch (sortBy) { 
  116. // You can supply 'sort' attributes to enable sorting of numbers, etc. 
  117. // For example, <td sort='2011/02/12'> for a date. 
  118. case 'text': 
  119. content = (elem.getAttribute('sort') ||  
  120. elem.firstChild.nodeValue).toLowerCase(); 
  121. break; 
  122. case 'number': 
  123. content = elem.numberValue; 
  124. break; 
  125. case 'date': 
  126. content = elem.dateValue; 
  127. break; 
  128. default: 
  129. content = (elem.getAttribute('sort') ||  
  130. elem.firstChild.nodeValue).toLowerCase(); 
  131. break; 
  132. } 
  133. j = elems.length; 
  134. if ( !aChild.id )  
  135. aChild.id = 'tempSortID' + j; 
  136. elems[j] = { data: content, tempID: aChild.id }; 
  137. } 
  138. } 
  139. // The following will determine if the table/etc has already been sorted  
  140. // by the same column or tag. If so, it will sort in ascending or descending  
  141. // order. It creates custom element properties to the parent element to  
  142. // remember the previous sort details. 
  143. if ( typeof colIndex == 'undefined' ) colIndex = 0; 
  144. if ( parent.prevTag && parent.prevTag == ((typeof colTag == 'undefined') ?  
  145. childTag : colTag) ) { 
  146. if (parent.prevCol == colIndex) { 
  147. // sorting by the same column as previously 
  148. parent.prevSort = (parent.prevSort == 'asc') ? 'desc' : 'asc'; 
  149. } else { // sorting by any other column 
  150. parent.prevCol = colIndex; 
  151. parent.prevSort = 'asc'; 
  152. } 
  153. } else { 
  154. // sorting for the 1st time or by a different tag 
  155. parent.prevTag = ((typeof colTag == 'undefined') ? childTag : colTag); 
  156. parent.prevCol = colIndex; 
  157. parent.prevSort = 'asc'; 
  158. } 
  159. if ( parent.prevSort === 'desc' ) { 
  160. // 'desc' WILL BE the previous sort order.. 
  161. switch (sortBy) { 
  162. case 'text': elems.sort(DescText); break; 
  163. case 'number': elems.sort(DescNum); break; 
  164. case 'date': elems.sort(DescNum); break; 
  165. default: elems.sort(DescText); break; 
  166. } 
  167. } else { 
  168. switch (sortBy) { 
  169. case 'text': elems.sort(AscText); break; 
  170. case 'number': elems.sort(AscNum); break; 
  171. case 'date': elems.sort(AscNum); break; 
  172. default: elems.sort(AscText); break; 
  173. } 
  174. } 
  175. frag = document.createDocumentFragment(); 
  176. for (i = 0, sortedLen = elems.length; i < sortedLen; i++) { 
  177. elem = document.getElementById(elems[i].tempID); 
  178. frag.appendChild(elem); 
  179. if ( (elem.id).substr(0,10) == 'tempSortID' ) 
  180. elem.removeAttribute('id'); 
  181. } 
  182. parent.appendChild(frag); 
  183. elems = null; 
  184. return parent.prevSort; // not currently used 
  185. }; 
  186. var AddSortToTables = function () { 
  187. // ..if table has class-name 'sortIt' 
  188. var tables = document.getElementsByTagName('table'), i, j,  
  189. tblLen, tbl, hdrs, hdrsLen; 
  190. function PreserveSortScope(a,b,c,d) { 
  191. return function () { 
  192. // assign the SortElements fn. to a table header 
  193. SortElements(a, b, c, d); 
  194. } 
  195. } 
  196. // add sorting to table headers 
  197. for ( i = 0, tblLen = tables.length; i < tblLen; i++ ) {  
  198. tbl = tables[i]; 
  199. if ( tbl.className.indexOf('sortIt') + 1) { 
  200. hdrs = tbl.getElementsByTagName('th'); 
  201. if ( hdrs ) { 
  202. for ( j = 0, hdrsLen = hdrs.length; j < hdrsLen; j++ ) { 
  203. AddEvent(hdrs[j],'click',PreserveSortScope(tbl,'tr','td',j)); 
  204. // if there's no title already, add "Click to sort" 
  205. if ( !hdrs[j].title ) hdrs[j].setAttribute('title', 
  206. 'Click to sort'); 
  207. } 
  208. } 
  209. } 
  210. } 
  211. }; 
  212. var AddSortByDate = function (tbl, col, dateMask) { 
  213. // Input: the table name (or object), a column index (or array)  
  214. // and a date mask ('dd-mmm-yy') 
  215. // Adds a sortBy = 'date' property to the first row 
  216. // will ignore the first row, assuming it is a header row 
  217. var i, rLen, cell; 
  218. while ( col.length ) AddSortByDate(tbl,col.pop(),dateMask); 
  219. if ((col instanceof Array) || isNaN(col)) return; 
  220. var tbl = (typeof tbl === 'string') ? document.getElementById(tbl) : tbl; 
  221. tbl.rows[0].cells[col].sortBy = 'date'; 
  222. AddSortByDate2(tbl, 'tr', 'td', col, dateMask); 
  223. }; 
  224. var AddSortByDate2 = function (parentEl, childTag, colTag, colIndex, dateMask) { 
  225. var kids, startAt = 0, i, rLen, cell; 
  226. var parent = (typeof parentEl === 'string') ?  
  227. document.getElementById(parentEl) : parentEl; 
  228. if ( parent.nodeName.toLowerCase() == 'table' ) { 
  229. parent = parent.tBodies[0] || parent; 
  230. startAt = ( parent.rows[0].cells[0].nodeName.toLowerCase() == 'th' ) * 1; 
  231. } 
  232. kids = parent.getElementsByTagName(childTag); 
  233. for ( i = startAt, rLen = kids.length; i < rLen; i++) { 
  234. cell = kids[i].getElementsByTagName(colTag)[colIndex]; 
  235. if (cell) { 
  236. if ( typeof cell.numberValue != 'undefined' ) delete cell.numberValue; 
  237. // the above enables switching from a number to a date sort  
  238. // (although v. unlikely) 
  239. if (cell.getAttribute('sort')) { 
  240. // use sort attribute if present 
  241. cell.dateValue = new Date(cell.getAttribute('sort')); 
  242. } else { 
  243. cell.dateValue = new Date(StringToDate(cell.firstChild.nodeValue,  
  244. dateMask)); 
  245. } 
  246. if (cell.dateValue.toString() == "NaN" || cell.dateValue.toString() ==  
  247. "Invalid Date") { 
  248. cell.dateValue = 0; 
  249. }  
  250. } 
  251. } 
  252. }; 
  253. var AddSortByNumber = function (tbl, col) { 
  254. // col is a column index or array of indices 
  255. // will ignore the first row, assuming it is a header row 
  256. var i, rLen, cell, tempNum; 
  257. while ( col.length ) AddSortByNumber(tbl,col.pop()); 
  258. if ((col instanceof Array) || isNaN(col)) return; 
  259. tbl = (typeof tbl === 'string') ? document.getElementById(tbl) : tbl; 
  260. tbl.rows[0].cells[col].sortBy = 'number'; 
  261. AddSortByNumber2(tbl,'tr','td',col); 
  262. }; 
  263. var AddSortByNumber2 = function (parentEl, childTag, colTag, colIndex) { 
  264. var kids, startAt = 0, i, rLen, cell, tempNum; 
  265. var parent = (typeof parentEl === 'string') ?  
  266. document.getElementById(parentEl) : parentEl; 
  267. if ( parent.nodeName.toLowerCase() == 'table' ) { 
  268. parent = parent.tBodies[0] || parent; 
  269. startAt = (parent.rows[0].cells[0].nodeName.toLowerCase() == 'th') * 1; 
  270. } 
  271. kids = parent.getElementsByTagName(childTag); 
  272. for (i = startAt, rLen = kids.length; i < rLen; i++) { 
  273. cell = kids[i].getElementsByTagName(colTag)[colIndex]; 
  274. if (cell) { 
  275. if ( typeof cell.dateValue != 'undefined' ) delete cell.dateValue; 
  276. // the above enables switching from a date to a number sort 
  277. // (although v. unlikely) 
  278. tempNum = cell.getAttribute('sort') || cell.firstChild.nodeValue; 
  279. tempNum = tempNum.replace(/[^0-9.-]/g, ''); 
  280. cell.numberValue = parseFloat(tempNum); 
  281. if (isNaN(cell.numberValue))  
  282. cell.numberValue = 0.0; 
  283. } 
  284. } 
  285. }; 
  286. var StringToDate = function (sDate, sFormat, cutOff) { 
  287. // Input: a date value as a string, it's format as a string e.g. 'dd-mmm-yy' 
  288. // Optional: a cutoff (integer) for 2 digit years. 
  289. // If no 'd' appears in the format string then the 1st of the month is assumed. 
  290. // If the year is 20 and the cut-off is 30 then the value will be converted  
  291. // to 2020; if the year is 40 then this will be converted to 1940. 
  292. // If no cut-off is supplied then '20' will be pre-pended to the year (YY). 
  293. // Output: a string in the format 'YYYY/MM/DD' or '' 
  294. // Will not attempt to convert certain combinations e.g. DMM, MDD, DDM, YYYYD. 
  295. var sParsed, fndSingle; 
  296. // sParsed will be constructed in the format 'YYYY/MM/DD' 
  297. sDate = sDate.toString().toUpperCase(); 
  298. sFormat = sFormat.toUpperCase(); 
  299. if (sFormat.search(/MMMM|MMM/) + 1) { // replace Mar/March with 03, etc. 
  300. sDate = sDate.replace(new RegExp('(' + ShortMths.join('|') + ')[A-Z]*', 'gi'), 
  301. function (m) { 
  302. var i = ShortMths.indexOf(m.charAt(0).toUpperCase() +  
  303. m.substr(1, 2).toLowerCase()) + 1; 
  304. return ((i < 10) ? "0" + i : "" + i).toString(); 
  305. }); 
  306. sFormat = sFormat.replace(/MMMM|MMM/g, 'MM'); 
  307. } 
  308. if (sFormat.search(/DDDD|DDD/) + 1) { // replace Tue/Tuesday, etc. with '' 
  309. sDate = sDate.replace(new RegExp('(' + ShortDays.join('|') + ')[A-Z]*', 'gi'),''); 
  310. sFormat = sFormat.replace(/DDDD|DDD/g, ''); 
  311. } 
  312. sDate = sDate.replace(/(^|/D)(/d)(?=/D|$)/g, function($0, $1, $2) { 
  313. // single digits 2 with 02 
  314. return $1 + '0' + $2; 
  315. }); 
  316. sFormat = sFormat.replace(/(^|[^DMY])(D|M)(?=[^DMY]|$)/g, function($0, $1, $2){ 
  317. return $1 + $2 + $2; // replace D or M with DD and MM 
  318. }); 
  319. // are there still single Ds or Ms? 
  320. fndSingle = sFormat.search(/(^|[^D])D([^D]|$)|(^|[^M])M([^M]|$)/)+1; 
  321. if ( fndSingle ) return ''; // do not attempt to parse, for example, 'DMM' 
  322. sFormat = sFormat.replace(/(^|[^Y])(YY)(?=[^Y]|$)/g, function($0, $1, $2, index) { 
  323. var tempDate = sDate.substr(0, index + 1); 
  324. tempDate += (cutOff) ? ((parseInt(sDate.substr(index + 1, 2),10) > cutOff) ?  
  325. '19' : '20') : '20'; 
  326. tempDate += sDate.substr(index + 1); 
  327. sDate = tempDate; 
  328. return $1 + $2 + $2; 
  329. }); 
  330. sParsed = ('YYYY/MM/DD').replace(/YYYY|MM|DD/g, function(m){ 
  331. return (sFormat.indexOf(m) + 1) ?  
  332. sDate.substr(sFormat.indexOf(m), m.length) : ''; 
  333. }); 
  334. if (sParsed.charAt(0) == '/') { 
  335. // if no year specified, assume the current year 
  336. sParsed = (new Date().getFullYear()) + sParsed; 
  337. } 
  338. if (sParsed.charAt(sParsed.length - 1) == '/') { 
  339. // if no date, assume the 1st of the month 
  340. sParsed += '01'; 
  341. } 
  342. // should end up with 10 characters.. 
  343. return ( sParsed.length == 10 ) ? sParsed : ''; 
  344. }; 

希望本文所述对大家的javascript程序设计有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选