您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
展开多少届。直观看到用户是多少届的
当前为
您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
- // ==UserScript==
- // @name nowcoder extend class
- // @description 展开多少届。直观看到用户是多少届的
- // @version 1.1
- // @include https://www.nowcoder.com/search/*
- // @include https://www.nowcoder.com/feed/main/detail/*
- // @namespace baojie.nowcoder
- // @license MIT
- // @grant GM_xmlhttpRequest
- // ==/UserScript==
- (function() {
- 'use strict';
- // Cache to store user IDs and their graduation years
- const userCache = new Map();
- // Set to track user IDs that have been processed
- const processedUserIds = new Set();
- // Add CSS styles for graduation year display
- function addStyles() {
- // Check if styles already added
- if (document.getElementById('nowcoder-grad-year-styles')) {
- return;
- }
- const styleElement = document.createElement('style');
- styleElement.id = 'nowcoder-grad-year-styles';
- styleElement.textContent = `
- .grad-year-display {
- color: #ff7830;
- margin-left: 5px;
- font-size: 12px;
- font-weight: bold;
- }
- `;
- document.head.appendChild(styleElement);
- }
- // Extract user ID from element
- function getUserIdFromElement(element) {
- // For links with href attribute
- if (element.tagName === 'A' && element.href) {
- const match = element.href.match(/\/users\/(\d+)/);
- if (match && match[1]) {
- return match[1];
- }
- }
- // For other elements, check parent or child links
- const link = element.closest('a[href*="/users/"]') ||
- element.querySelector('a[href*="/users/"]');
- if (link) {
- const match = link.href.match(/\/users\/(\d+)/);
- if (match && match[1]) {
- return match[1];
- }
- }
- return null;
- }
- // Display the graduation year next to the user name
- function displayGradYear(element, gradYear) {
- // Find the appropriate container
- const nameSpan = element.querySelector('.name-text');
- // Check if we already added to this specific element
- if (nameSpan.querySelector('.grad-year-display') || element.hasAttribute('data-grad-displayed')) {
- return;
- }
- // Create the graduation year display
- const gradYearElement = document.createElement('span');
- gradYearElement.className = 'grad-year-display';
- gradYearElement.textContent = `(${gradYear})`;
- gradYearElement.setAttribute('data-userid', element.getAttribute('data-userid'));
- // Add to the page
- nameSpan.appendChild(gradYearElement);
- // Mark this element as having the graduation year displayed
- element.setAttribute('data-grad-displayed', 'true');
- }
- // Fetch user info using GM_xmlhttpRequest
- function fetchUserInfo(userId) {
- return new Promise((resolve) => {
- const url = `https://gw-c.nowcoder.com/api/sparta/user/info/card/${userId}?_=${Date.now()}`;
- // Use GM_xmlhttpRequest directly, avoiding the unsafe header issue
- GM_xmlhttpRequest({
- method: 'GET',
- url: url,
- headers: {
- 'Accept': 'application/json',
- 'X-Requested-With': 'XMLHttpRequest'
- // Removed Referer header to avoid the 'unsafe header' error
- },
- onload: function(response) {
- try {
- const data = JSON.parse(response.responseText);
- if (data.success && data.data && data.data.workTime) {
- resolve(data.data.workTime);
- } else {
- resolve(null);
- }
- } catch (e) {
- console.error('Failed to parse response', e);
- resolve(null);
- }
- },
- onerror: function() {
- resolve(null);
- }
- });
- });
- }
- // Process a single user element
- async function processUserElement(element) {
- // Skip if already fully processed
- if (element.hasAttribute('data-grad-displayed')) {
- return;
- }
- const userId = getUserIdFromElement(element);
- if (!userId) {
- return;
- }
- // Store userId as data attribute to help with duplicate detection
- element.setAttribute('data-userid', userId);
- // Skip if already in progress for this user ID
- if (processedUserIds.has(userId)) {
- // If we already know this user's info, display it
- if (userCache.has(userId)) {
- displayGradYear(element, userCache.get(userId));
- }
- return;
- }
- // Mark as being processed
- processedUserIds.add(userId);
- // Check cache first
- if (userCache.has(userId)) {
- displayGradYear(element, userCache.get(userId));
- return;
- }
- // Fetch user info
- const gradYear = await fetchUserInfo(userId);
- if (gradYear) {
- userCache.set(userId, gradYear);
- // Update all instances of this user on the page
- document.querySelectorAll(`[data-userid="${userId}"]:not([data-grad-displayed])`).forEach(el => {
- displayGradYear(el, gradYear);
- });
- }
- }
- // Process all user elements visible on the page
- function processVisibleElements() {
- // Find all user name links
- document.querySelectorAll('a[href*="/users/"]').forEach(link => {
- if (link.closest('.user-nickname') || link.querySelector('.name-text')) {
- processUserElement(link);
- }
- });
- }
- // Simple debounce function
- function debounce(func, wait) {
- let timeout;
- return function() {
- const context = this, args = arguments;
- clearTimeout(timeout);
- timeout = setTimeout(() => func.apply(context, args), wait);
- };
- }
- // Initialize
- function init() {
- console.log('Nowcoder graduation year display script initialized');
- addStyles();
- // Initial processing with a short delay
- setTimeout(processVisibleElements, 500);
- // Process on scroll (debounced)
- window.addEventListener('scroll', debounce(processVisibleElements, 300));
- // Process on content changes
- const observer = new MutationObserver(debounce(mutations => {
- let hasNewNodes = false;
- mutations.forEach(mutation => {
- if (mutation.addedNodes.length > 0) {
- hasNewNodes = true;
- }
- });
- if (hasNewNodes) {
- processVisibleElements();
- }
- }, 300));
- observer.observe(document.body, { childList: true, subtree: true });
- }
- // Run after page has loaded
- if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', init);
- } else {
- init();
- }
- })();