Скрипт на скрытие комментариев от заблокированных пользователей

Недавно жаловался на ДТФ на ботов от плохих людей , которые засирают комменты. Которые даже если блочишь, всё равно видишь мусор на экране. Вот зачем мне видеть "Комментарий заблокирован" если на него нет ответов, а?

Пришлось воспользоваться советом одного человека. Который правда не справился, но верю что мне повезет.

Если хочешь что-нибудь сделать, сделай это сам. Вот так.

Скрипт полностью скрывает комментарии которые заблокированы/удалены и не имеют незаблокированных ответов. Т.е. отдельные комменты, а так же ветки где смотреть нечего.

Скрипт для Violentmonkey (или альтернатив). Я не веб разработчик, я ненавижу фронтэнд, и разбираюсь в нём как свинья в апельсинах, да и вообще он большей частью навайбкоден. Я только проверил что он похоже рабочий и похоже что не делает ничего кроме того что запрошено. Но если у вас DTF начнёт работать со скоростью черепахи или вдруг скроется что-то не то, то здоровья вам и хорошего настроения. Сей результат отдаю в общественное достояние (public domain), так что если кто хочет и может сделать лучше - пожалуйста делайте.

Как пользоваться: в ViolentMonkey нажать создание нового скрипта (плюсик) и скопировать туда код.

Апд 1.1 Скрипт улучшен чтобы меньше нагружал систему. Спасибо Nikos за совет

// ==UserScript== // @name Hide Empty Hidden Comments // @namespace http://tampermonkey.net/ // @match https://dtf.ru/* // @version 1.2 // @description Прячет скрытые комментарии если у них нет видимых потомков // @grant none // ==/UserScript== (function () { 'use strict'; const TREE_SELECTOR = '.comments-tree'; const HIDDEN_CLASS = 'comment--hidden'; // --- Debounce --- function debounce(fn, ms) { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => fn(...args), ms); }; } // --- Core logic (unchanged) --- function hasExpandableChildren(comment) { const btn = comment.querySelector('.comment__expand'); if (!btn) return false; return btn.textContent.trim() !== 'Свернуть'; } function hasVisibleDescendant(comment) { if (hasExpandableChildren(comment)) return true; const myLevel = parseInt(comment.style.getPropertyValue('--comment-display-level')); let sibling = comment.nextElementSibling; while (sibling) { if (sibling.style.display === 'none') { sibling = sibling.nextElementSibling; continue; } const sibLevel = parseInt(sibling.style.getPropertyValue('--comment-display-level')); if (sibLevel <= myLevel) break; if (sibling.classList.contains('comment')) { if (!sibling.classList.contains(HIDDEN_CLASS)) return true; if (hasExpandableChildren(sibling)) return true; } sibling = sibling.nextElementSibling; } return false; } function processTree(tree) { const obs = tree.__commentObserver; if (obs) obs.disconnect(); const hiddenComments = [...tree.querySelectorAll(`.comment.${HIDDEN_CLASS}`)]; // Обрабатываем снизу вверх — сначала самые глубокие hiddenComments.reverse(); for (const comment of hiddenComments) { if (hasVisibleDescendant(comment)) { comment.style.removeProperty('display'); } else { comment.style.display = 'none'; } } if (obs) obs.observe(tree, TREE_OBSERVER_OPTIONS); } const TREE_OBSERVER_OPTIONS = { childList: true, subtree: true, attributes: true, attributeFilter: ['class', 'style'], }; function attachToTree(tree) { if (tree.dataset.observed) return; tree.dataset.observed = 'true'; processTree(tree); const debouncedProcess = debounce(() => processTree(tree), 200); const treeObserver = new MutationObserver((mutations) => { // Only react if a .comment node was added, or class/style changed on one const relevant = mutations.some(m => { if (m.type === 'childList') { return [...m.addedNodes].some(n => n.nodeType === 1 && (n.classList.contains('comment') || n.querySelector?.('.comment')) ); } if (m.type === 'attributes') { return m.target.classList.contains('comment'); } return false; }); if (relevant) debouncedProcess(); }); tree.__commentObserver = treeObserver; treeObserver.observe(tree, TREE_OBSERVER_OPTIONS); } // --- Root observer: watches for trees appearing in the SPA --- const debouncedScan = debounce(() => { document.querySelectorAll(TREE_SELECTOR).forEach(attachToTree); }, 300); const rootObserver = new MutationObserver((mutations) => { const relevant = mutations.some(m => [...m.addedNodes].some(n => n.nodeType === 1 && (n.matches?.(TREE_SELECTOR) || n.querySelector?.(TREE_SELECTOR)) ) ); if (relevant) debouncedScan(); }); rootObserver.observe(document.body, { childList: true, subtree: true }); // Initial scan if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', debouncedScan); } else { debouncedScan(); } })();
3
1
12 комментариев