各位佬友,大家好!我在用 Cressida大佬的 “LINUX DO活跃助手” 脚本 的时候,发现在有些浏览器上跑不起来,就自己动手稍微改了一下,修改了一些小问题,现在可以在更多浏览器上顺利运行了。
我调整了一下代码,解决了一些浏览器在执行过程中遇到的加载和找不到元素的问题。加了一些错误处理,现在即使页面结构有点变化也不容易报错,还增加了调试信息,方便排查。
大家把下面的代码复制到油猴插件里,创建一个新的脚本,保存之后刷新L站,会多出一个按钮,大家点击它脚本就启动了!
// ==UserScript==
// @name LINUX DO活跃助手(PiliPala修复版)
// @namespace https://linux.do
// @version 1.0
// @description 基于Cressida的自动阅读脚本,做了一些小的修改并修复了部分浏览器无法正常运行的问题
// @author Cressida & PiliPala
// @match https://linux.do/*
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
(function () {
'use strict';
const config = {
scrollInterval: 300, // 滚动间隔(毫秒)
scrollStep: 880, // 每次滚动的像素
waitForElement: 20000, // 找不到评论的最大时间
waitingTime: 1 // 看完评论等待N秒进入新帖子
};
function getSwitchState() {
return GM_getValue('linuxdoHelperEnabled', false);
}
function toggleSwitch() {
const currentState = getSwitchState();
GM_setValue('linuxdoHelperEnabled', !currentState);
if (!currentState) {
window.location.href = "https://linux.do/new";
}
console.log(`Linuxdo助手已${!currentState ? '启用' : '禁用'}`);
}
function createSwitchIcon() {
const iconLi = document.createElement('li');
iconLi.className = 'header-dropdown-toggle';
const iconLink = document.createElement('a');
iconLink.href = 'javascript:void(0)';
iconLink.className = 'btn no-text icon btn-flat';
iconLink.title = getSwitchState() ? '停止Linuxdo助手' : '启动Linuxdo助手';
iconLink.tabIndex = 0;
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('class', 'fa d-icon d-icon-rocket svg-icon prefix-icon svg-string');
const use = document.createElementNS('http://www.w3.org/2000/svg', 'use');
use.setAttribute('href', getSwitchState() ? '#pause' : '#play');
svg.appendChild(use);
iconLink.appendChild(svg);
iconLi.appendChild(iconLink);
iconLink.addEventListener('click', () => {
toggleSwitch();
const currentState = getSwitchState();
use.setAttribute('href', currentState ? '#pause' : '#play');
iconLink.title = currentState ? '停止Linuxdo助手' : '启动Linuxdo助手';
iconLink.classList.toggle('active', currentState);
});
const chatIconLi = document.querySelector('li.search-dropdown.header-dropdown-toggle');
if (chatIconLi) {
chatIconLi.parentNode.insertBefore(iconLi, chatIconLi.nextSibling);
}
}
async function waitForElement(selectors) {
return new Promise((resolve, reject) => {
const checkSelectors = () => {
for (const selector of selectors) {
const element = document.querySelector(selector);
if (element) {
resolve(element);
return true;
}
}
return false;
};
if (checkSelectors()) return;
const observer = new MutationObserver(() => {
if (checkSelectors()) {
observer.disconnect();
}
});
observer.observe(document.body, { childList: true, subtree: true });
setTimeout(() => {
observer.disconnect();
reject(new Error(`未找到元素:${selectors.join(' 或 ')}`));
}, config.waitForElement);
});
}
function getRawLinks() {
const rawLinkElements = document.querySelectorAll('.raw-link');
return Array.from(rawLinkElements).map((element, index) => ({
index: index + 1,
href: element.href,
text: element.textContent.trim()
})).filter(link => link.href);
}
function loadPage(links) {
if (!getSwitchState()) { return; }
const visitedLinks = JSON.parse(localStorage.getItem('visitedLinks') || '[]');
const unvisitedLinks = links.filter(link => !visitedLinks.includes(link.href));
if (unvisitedLinks.length === 0) {
window.location.href = "https://linux.do/new";
console.log("去看最新帖子");
return;
}
const selectedLink = unvisitedLinks[Math.floor(Math.random() * unvisitedLinks.length)];
visitedLinks.push(selectedLink.href);
localStorage.setItem('visitedLinks', JSON.stringify(visitedLinks));
window.location.href = selectedLink.href;
}
function scrollComment(CommentElement) {
let count = 0;
const scrollInterval = setInterval(() => {
CommentElement.scrollTop += config.scrollStep;
CommentElement.dispatchEvent(new Event('scroll'));
const links = getRawLinks();
if (links.length > 0) {
count++;
if (count * config.scrollInterval / 1000 >= config.waitingTime) {
clearInterval(scrollInterval);
loadPage(links);
}
}
}, config.scrollInterval);
}
function main() {
createSwitchIcon();
if (!getSwitchState()) return;
try {
start();
} catch (error) {
console.error('脚本执行出错:', error);
}
}
async function start() {
try {
const selectors = [
'html.desktop-view',
'html.not-mobile-device',
'html.text-size-normal',
'html.no-touch',
'html.discourse-no-touch'
];
const Comment = await waitForElement(selectors);
scrollComment(Comment);
} catch (error) {
console.error(error.message);
}
}
if (document.readyState === 'complete') {
main();
} else {
window.addEventListener('load', main);
}
})();
如果大家觉得有用,就点个赞吧!新人发帖,希望各位佬友多多关照