FreshRSS Double-Tap and Auto-Scroll

Double-tap to close active articles and auto-scroll to the active article in FreshRSS

当前为 2025-02-04 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name FreshRSS Double-Tap and Auto-Scroll
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.1
  5. // @description Double-tap to close active articles and auto-scroll to the active article in FreshRSS
  6. // @author Your Name
  7. // @homepage https://greasyfork.org/en/scripts/525912
  8. // @match http://192.168.1.2:1030/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14. // Debug mode
  15. const DEBUG = false;
  16. function debugLog(message) {
  17. if (DEBUG) {
  18. console.log(`[FreshRSS Script]: ${message}`);
  19. }
  20. }
  21. debugLog('Script loaded');
  22.  
  23. // Function to scroll to element
  24. function scrollToElement(element) {
  25. if (element) {
  26. const header = document.querySelector('header');
  27. const headerHeight = header ? header.offsetHeight : 0;
  28. const elementPosition = element.getBoundingClientRect().top + window.pageYOffset;
  29. const offsetPosition = elementPosition - headerHeight - 10;
  30.  
  31. window.scrollTo({
  32. top: offsetPosition,
  33. behavior: 'smooth'
  34. });
  35. debugLog('Scrolling to element: ' + element.id);
  36. }
  37. }
  38.  
  39. // Handle double-tap to close
  40. document.addEventListener('dblclick', function(event) {
  41. const interactiveElements = ['A', 'BUTTON', 'INPUT', 'TEXTAREA', 'SELECT', 'LABEL'];
  42. if (interactiveElements.includes(event.target.tagName)) {
  43. debugLog('Ignored double-tap on interactive element');
  44. return;
  45. }
  46.  
  47. const activeElement = event.target.closest('.flux.active');
  48. if (activeElement) {
  49. activeElement.classList.remove('active');
  50. debugLog('Closed article via double-tap');
  51. // scrollToElement(activeElement);
  52. activeElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
  53. }
  54. });
  55.  
  56. // mutation observer to catch programmatic changes
  57. const observer = new MutationObserver((mutations) => {
  58. mutations.forEach((mutation) => {
  59. if (mutation.target.classList && mutation.target.classList.contains('flux')) {
  60. if (mutation.target.classList.contains('active')) {
  61. debugLog('Article became active via mutation');
  62. scrollToElement(mutation.target);
  63. }
  64. }
  65. });
  66. });
  67.  
  68. // Start observing the document with the configured parameters
  69. observer.observe(document.body, {
  70. attributes: true,
  71. attributeFilter: ['class'],
  72. subtree: true
  73. });
  74. })();