🎉 欢迎访问GreasyFork.Org 镜像站!本镜像站由公众号【爱吃馍】搭建,用于分享脚本。联系邮箱📮

Greasy fork 爱吃馍镜像

知乎答主H指数统计

在知乎答主主页统计回答的h-index

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(У мене вже є менеджер скриптів, дайте мені встановити його!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

// ==UserScript==
// @name         知乎答主H指数统计
// @version      1.2
// @description  在知乎答主主页统计回答的h-index
// @author       @高耗氧动物
// @namespace    https://www.zhihu.com/people/czarja
// @match        https://www.zhihu.com/people/*/answers*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';


    GM_addStyle(`
        .stats-loader {
            padding: 12px 16px;
            border-bottom: 1px solid #f0f2f7;
            cursor: pointer;
            color: #0084ff;
            font-weight: 600;
            display: flex;
            align-items: center;
        }
        .stats-loader:hover {
            background-color: #f6f6f6;
        }
        .stats-loader svg {
            margin-right: 8px;
        }
        .stats-container {
            padding: 12px 16px;
            border-bottom: 1px solid #f0f2f7;
        }
        .stats-item {
            margin-bottom: 8px;
            display: flex;
            justify-content: space-between;
        }
    `);

    // 等待页面加载完成
    window.addEventListener('load', function() {
        const cardHeader = document.querySelector('.Card .Card-header');
        if (!cardHeader) return;

        // 找到Card-header的父元素
        // const card = cardHeader.parentElement;
        // if (!card) return;

        // 创建加载按钮
        const loader = document.createElement('div');
        loader.className = 'stats-loader';
        loader.innerHTML = `
            <svg width="1.2em" height="1.2em" viewBox="0 0 24 24" fill="currentColor">
            <path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"/>
            </svg>
            点击加载统计
        `;

        // 创建统计结果容器
        const statsContainer = document.createElement('div');
        statsContainer.className = 'stats-container';
        statsContainer.style.display = 'none';

        // 在Card-header之后插入元素
        cardHeader.insertAdjacentElement('afterend', statsContainer);
        cardHeader.insertAdjacentElement('afterend', loader);


        let hIndex = 0;
        loader.addEventListener('click', function() {
            if (statsContainer.style.display === 'none') {
                loader.innerHTML = `
                    <svg width="1.2em" height="1.2em" viewBox="0 0 24 24" fill="currentColor">
                        <path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46A7.93 7.93 0 0 0 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74A7.93 7.93 0 0 0 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/>
                    </svg>
                    正在加载统计...
                `;

                // 设置一个间隔检查,因为有些内容可能是异步加载的
                const interval = setInterval(function() {
                    // 查找所有可能的排序按钮
                    const buttons = document.querySelectorAll('#Popover4-toggle');
                    if (buttons[0].innerText.trim() !== "按赞同排序") {
                        buttons[0].click(); // 如果不是,则点击按钮
                        const buttons2 = document.querySelectorAll('#Select1-1');
                        buttons2[0].click()
                    }
                    clearInterval(interval);
                    (async () => {
                        const hIndex = await startAutoScroll();
                        //console.log(`finished with h= ${hIndex}`);

                        statsContainer.innerHTML = `
                         <div class="stats-item"><span>h-index:</span><span>${hIndex}</span></div>`;

                        statsContainer.style.display = 'block';

                        loader.innerHTML = `
                        <svg width="1.2em" height="1.2em" viewBox="0 0 24 24" fill="currentColor">
                            <path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"/>
                        </svg>
                        回答统计
                        `;

                        // 滚动回顶部
                        window.scrollTo({
                            top: 0,
                            behavior: 'smooth' // 平滑滚动
                        });

                        simulateEscapeKey();
                    })();

                    //console.log(`finished with h= ${hIndex}`);
                }, 500); // 每500毫秒检查一次

                // 10秒后如果还没找到,停止检查
                setTimeout(() => clearInterval(interval), 10000);
            } else {
                statsContainer.style.display = 'none';
                loader.innerHTML = `
                <svg width="1.2em" height="1.2em" viewBox="0 0 24 24" fill="currentColor">
                <path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"/>
                </svg>
               点击加载统计
                `;
            }
        });
    });

    function simulateEscapeKey() {
        // 创建键盘事件
        const escEvent = new KeyboardEvent('keydown', {
            key: 'Escape',
            code: 'Escape',
            keyCode: 27, // ESC 键的 keyCode
            bubbles: true, // 允许事件冒泡
            cancelable: true // 允许事件被取消
        });

        // 触发事件(通常在 document 或特定元素上)
        document.dispatchEvent(escEvent);
    }

    function startAutoScroll() {
        return new Promise((resolve) => {
            let scrollAttempts = 0;
            const maxAttempts = 100;
            const scrollDelay = 1500;
            let hIndex = 0;
            let prevAnswerLen = 0;
            let curAnswerLen = 0;

            const scrollInterval = setInterval(() => {
                if (scrollAttempts >= maxAttempts) {
                    clearInterval(scrollInterval);
                    //console.log('已达到最大滚动次数,停止自动加载');
                    resolve(hIndex);
                    return;
                }

                window.scrollTo({
                    top: document.body.scrollHeight,
                    behavior: 'smooth'
                });

                //console.log(`第 ${scrollAttempts + 1} 次滚动到底部,等待新内容加载...`);

                setTimeout(() => {
                    scrollAttempts++;
                }, scrollDelay);

                [hIndex, curAnswerLen] = extractData();
                //console.log(hIndex, curAnswerLen)

                if (hIndex < curAnswerLen) {
                    clearInterval(scrollInterval);
                    resolve(hIndex);
                    return;
                } else {
                    prevAnswerLen = curAnswerLen;
                }

            }, scrollDelay + 500);
        });
    }

    function extractData () {
        const answers = [];
        document.querySelectorAll('.ContentItem').forEach(item => {
            const upvoteMeta = item.querySelector('meta[itemprop="upvoteCount"]');
            const upvotes = upvoteMeta ? parseInt(upvoteMeta.getAttribute('content')) : 0;
            answers.push(upvotes);
        });
        let hIndex = 0;
        const n = answers.length;

        for (let i = 0; i < n; i++) {
            if (answers[i] >= i + 1) {
                hIndex = i + 1;
            } else {
                break;
            }
        }
        return [hIndex, n];
    };

})();