Hacker News Comment Sorter

Sort Hacker News comments by various attributes

  1. // ==UserScript==
  2. // @name Hacker News Comment Sorter
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2
  5. // @description Sort Hacker News comments by various attributes
  6. // @match https://news.ycombinator.com/item?id=*
  7. // @grant none
  8. // @author Osiris-Team
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. function createSortButton(text, sortFunction) {
  16. const button = document.createElement('button');
  17. button.textContent = text;
  18. button.addEventListener('click', sortFunction);
  19. return button;
  20. }
  21.  
  22. function getComments() {
  23. return Array.from(document.querySelectorAll('tr.athing.comtr'));
  24. }
  25.  
  26. function sortComments(compareFn) {
  27. const comments = getComments();
  28. const sortedComments = comments.sort(compareFn);
  29. const commentList = document.querySelector('table.comment-tree');
  30. sortedComments.forEach(comment => commentList.appendChild(comment));
  31. }
  32.  
  33. function sortByAge() {
  34. sortComments((a, b) => {
  35. const aAge = a.querySelector('.age').getAttribute('title');
  36. const bAge = b.querySelector('.age').getAttribute('title');
  37. return new Date(bAge) - new Date(aAge);
  38. });
  39. }
  40.  
  41. function sortByUser() {
  42. sortComments((a, b) => {
  43. const aUser = a.querySelector('.hnuser').textContent.toLowerCase();
  44. const bUser = b.querySelector('.hnuser').textContent.toLowerCase();
  45. return aUser.localeCompare(bUser);
  46. });
  47. }
  48.  
  49. function sortByIndentation() {
  50. sortComments((a, b) => {
  51. const aIndent = parseInt(a.querySelector('.ind img').getAttribute('width'));
  52. const bIndent = parseInt(b.querySelector('.ind img').getAttribute('width'));
  53. return aIndent - bIndent;
  54. });
  55. }
  56.  
  57. function sortByScore() {
  58. sortComments((a, b) => {
  59. const aScore = parseInt(a.querySelector('.score')?.textContent) || 0;
  60. const bScore = parseInt(b.querySelector('.score')?.textContent) || 0;
  61. return bScore - aScore;
  62. });
  63. }
  64.  
  65. function sortByCommentLength() {
  66. sortComments((a, b) => {
  67. const aLength = a.querySelector('.commtext').textContent.length;
  68. const bLength = b.querySelector('.commtext').textContent.length;
  69. return bLength - aLength;
  70. });
  71. }
  72.  
  73. function sortByCommentId() {
  74. sortComments((a, b) => {
  75. const aId = parseInt(a.id);
  76. const bId = parseInt(b.id);
  77. return aId - bId;
  78. });
  79. }
  80.  
  81. function sortByUserColor() {
  82. sortComments((a, b) => {
  83. const aColor = a.querySelector('.hnuser font')?.getAttribute('color') || '';
  84. const bColor = b.querySelector('.hnuser font')?.getAttribute('color') || '';
  85. return aColor.localeCompare(bColor);
  86. });
  87. }
  88.  
  89. function init() {
  90. const sortingDiv = document.createElement('div');
  91. sortingDiv.style.margin = '10px 0';
  92. sortingDiv.appendChild(createSortButton('Sort by Age', sortByAge));
  93. sortingDiv.appendChild(createSortButton('Sort by User', sortByUser));
  94. sortingDiv.appendChild(createSortButton('Sort by Indentation', sortByIndentation));
  95. sortingDiv.appendChild(createSortButton('Sort by Score', sortByScore));
  96. sortingDiv.appendChild(createSortButton('Sort by Comment Length', sortByCommentLength));
  97. sortingDiv.appendChild(createSortButton('Sort by Comment ID', sortByCommentId));
  98. sortingDiv.appendChild(createSortButton('Sort by User Color', sortByUserColor));
  99.  
  100. const commentSection = document.querySelector('table.comment-tree');
  101. commentSection.parentNode.insertBefore(sortingDiv, commentSection);
  102. }
  103.  
  104. init();
  105. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址