// ==UserScript== // @name Google Scholar Advanced Sorting Toolbox(year、cite) // @name:zh-CN 📚谷歌学术高级排序工具箱 (按年份、引用数) // @namespace http://tampermonkey.net/ // @version 2025.07.10.101 // @description 👍Supercharge your Google Scholar experience with a powerful, floating sorting toolbox. This script allows you to instantly sort results on the **current page**: 1. Sort by Year (Newest ↔ Oldest) 2. Sort by Citations (Highest ↔ Lowest)3. Data at a Glance 4. Intuitive UI // @description:zh-CN 👍为谷歌学术搜索结果页面添加一个功能强大的悬浮排序工具箱。你可以通过它轻松地对【当前页面】的文献进行排序:1.【按年份排序 (新→旧 / 旧→新)】:同年份的文献会自动按引用数从高到低排列。2.【按引用数排序 (高→低 / 低→高)】。3.【直观数据显示】:排序后,每条结果左侧将清晰地显示其年份和引用数。4.【状态高亮】:当前有效的排序按钮会高亮显示,且脚本能完美保留谷歌学术的原有页面布局。 // @author heyue // @match https://scholar.google.com/scholar?* // @match https://scholar.google.com.hk/scholar?* // @match https://sc.panda985.com/scholar?* // @icon https://www.google.com/s2/favicons?sz=64&domain=google.com // @grant none // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/542159/Google%20Scholar%20Advanced%20Sorting%20Toolbox%EF%BC%88year%E3%80%81cite%EF%BC%89.user.js // @updateURL https://update.greasyfork.icu/scripts/542159/Google%20Scholar%20Advanced%20Sorting%20Toolbox%EF%BC%88year%E3%80%81cite%EF%BC%89.meta.js // ==/UserScript== (function () { 'use strict'; let currentSortState = { key: null, descending: null }; // --- 数据提取辅助函数 --- function getYear(node) { const authorLine = node.querySelector('.gs_a'); if (!authorLine) return 0; const text = authorLine.textContent; const yearMatch = text.match(/\b(19|20)\d{2}\b/); return yearMatch ? parseInt(yearMatch[0], 10) : 0; } function getCiteCount(node) { const citeLink = node.querySelector('a[href*="/scholar?cites"]'); if (!citeLink) return 0; const citeMatch = citeLink.textContent.match(/\d+/); return citeMatch ? parseInt(citeMatch[0], 10) : 0; } // --- 核心排序与渲染逻辑 --- function sortElements(sortKey, isDescending) { const gsResCclMid = document.getElementById('gs_res_ccl_mid'); if (!gsResCclMid) return; const elementsWithData = [...gsResCclMid.querySelectorAll('.gs_or')] .map(node => ({ node: node, year: getYear(node), cite: getCiteCount(node) })); elementsWithData.sort((a, b) => { if (sortKey === 'year') { const yearDiff = isDescending ? b.year - a.year : a.year - b.year; if (yearDiff !== 0) return yearDiff; return b.cite - a.cite; } else { return isDescending ? b.cite - a.cite : a.cite - b.cite; } }); // 【关键改动】为每个结果项更新布局和信息 elementsWithData.forEach(item => { const { node, year, cite } = item; // --- 布局包裹逻辑 --- // 检查是否已经处理过(即是否已存在包裹容器) if (!node.querySelector('.gs-original-content-wrapper')) { const contentWrapper = document.createElement('div'); contentWrapper.className = 'gs-original-content-wrapper'; contentWrapper.style.flexGrow = '1'; // 让包裹容器占据剩余空间 // 将 node 的所有原始子元素移动到包裹容器中 while (node.firstChild) { contentWrapper.appendChild(node.firstChild); } // 将包裹容器加回 node node.appendChild(contentWrapper); } // --- 信息块创建与更新逻辑 --- let infoBox = node.querySelector('.gs-sort-info-box'); if (!infoBox) { infoBox = document.createElement('div'); infoBox.className = 'gs-sort-info-box'; Object.assign(infoBox.style, { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', width: '80px', flexShrink: '0', paddingRight: '15px', marginRight: '15px', borderRight: '1px solid #e0e0e0', textAlign: 'center' }); // 首次创建时,插入到最前面 node.prepend(infoBox); } // 无论是否首次创建,都更新信息块的内容 const yearText = year > 0 ? year : 'N/A'; const yearDisplay = `