Double-tap to close active articles and auto-scroll to the active article in FreshRSS
当前为
// ==UserScript==
// @name FreshRSS Double-Tap and Auto-Scroll
// @namespace http://tampermonkey.net/
// @version 2.0
// @description Double-tap to close active articles and auto-scroll to the active article in FreshRSS
// @author Your Name
// @homepage https://greasyfork.org/en/scripts/525912
// @match http://192.168.1.2:1030/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Debug mode
const DEBUG = false;
function debugLog(message) {
if (DEBUG) {
console.log(`[FreshRSS Script]: ${message}`);
}
}
debugLog('Script loaded');
// Function to scroll to element
function scrollToElement(element) {
if (element) {
const header = document.querySelector('header');
const headerHeight = header ? header.offsetHeight : 0;
const elementPosition = element.getBoundingClientRect().top + window.pageYOffset;
const offsetPosition = elementPosition - headerHeight - 10;
window.scrollTo({
top: offsetPosition,
behavior: 'smooth'
});
debugLog('Scrolling to element: ' + element.id);
}
}
// Handle double-tap to close
document.addEventListener('dblclick', function(event) {
const interactiveElements = ['A', 'BUTTON', 'INPUT', 'TEXTAREA', 'SELECT', 'LABEL'];
if (interactiveElements.includes(event.target.tagName)) {
debugLog('Ignored double-tap on interactive element');
return;
}
const activeElement = event.target.closest('.flux.active');
if (activeElement) {
activeElement.classList.remove('active');
debugLog('Closed article via double-tap');
// scrollToElement(activeElement);
activeElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
});
// Monitor for new active articles using both click and mutation events
document.addEventListener('click', function(event) {
const fluxElement = event.target.closest('.flux');
if (fluxElement) {
// Use a shorter delay and check multiple times
const checkInterval = setInterval(() => {
if (fluxElement.classList.contains('active')) {
debugLog('Article became active via click');
scrollToElement(fluxElement);
clearInterval(checkInterval);
}
}, 100); // Check every 100ms
// Stop checking after 1 second to prevent infinite checking
setTimeout(() => clearInterval(checkInterval), 1000);
}
});
// Additional mutation observer to catch programmatic changes
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.target.classList && mutation.target.classList.contains('flux')) {
if (mutation.target.classList.contains('active')) {
debugLog('Article became active via mutation');
scrollToElement(mutation.target);
}
}
});
});
// Start observing the document with the configured parameters
observer.observe(document.body, {
attributes: true,
attributeFilter: ['class'],
subtree: true
});
})();