知乎问题标记已读

在知乎问题标题旁添加标记为已读的按钮,并允许反复切换状态

// ==UserScript==
// @name         知乎问题标记已读
// @namespace    http://tampermonkey.net/
// @version      0.8
// @description  在知乎问题标题旁添加标记为已读的按钮,并允许反复切换状态
// @author       shaoz
// @match        *://*.zhihu.com/*
// @grant        none
// @run-at       document-end
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    function addButton(element, questionId) {
        if (element.querySelector('.mark-as-read')) {
            return; // 避免重复添加按钮
        }

        const isRead = localStorage.getItem('read_' + questionId) === 'true';

        const readButton = document.createElement('button');
        readButton.className = 'mark-as-read';
        readButton.innerText = isRead ? '已读' : '标记为已读';
        readButton.style.marginLeft = '10px';
        readButton.style.color = '#000000';
        readButton.style.backgroundColor = isRead ? '#4CAF50' : '#e0e0e0';
        readButton.style.border = '1px solid #dcdcdc';
        readButton.style.padding = '1px 4px';
        readButton.style.fontSize = '12px';
        readButton.style.fontWeight = 'normal';
        readButton.style.cursor = 'pointer';

        readButton.onclick = function() {
            const currentState = localStorage.getItem('read_' + questionId) === 'true';
            localStorage.setItem('read_' + questionId, !currentState);
            this.style.backgroundColor = currentState ? '#e0e0e0' : '#4CAF50';
            this.innerText = currentState ? '标记为已读' : '已读';
        };

        // 使按钮在标题的同一行显示
        element.style.display = 'inline-flex';
        element.style.alignItems = 'center';
        element.appendChild(readButton);
    }

    function processPage() {
        // 尝试从详情页获取问题ID
        const dataElement = document.getElementById('js-initialData');
        if (dataElement) {
            try {
                const initialData = JSON.parse(dataElement.textContent);
                const questionId = initialData.initialState.entities.questions[Object.keys(initialData.initialState.entities.questions)[0]].id;
                const titleElement = document.querySelector('.QuestionHeader-title');
                if (titleElement) {
                    addButton(titleElement, questionId);
                }
            } catch (e) {
                console.error('Error parsing initial data:', e);
            }
        }

        // 主页或搜索结果页
        document.querySelectorAll('.ContentItem-title, .SearchResult-Card .ContentItem-title').forEach(title => {
            const linkElement = title.querySelector('a[href*="/question/"]');
            if (linkElement) {
                const href = linkElement.getAttribute('href');
                const match = href.match(/question\/(\d+)/);
                if (match) {
                    addButton(title, match[1]);
                }
            }
        });
    }

    const observer = new MutationObserver(mutations => {
        processPage();
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });

    processPage();
})();