为gmgn.ai网站的钱包地址添加Solscan跳转按钮,但在特定区域内不显示
// ==UserScript==
// @name GMGN Solscan 跳转按钮
// @namespace http://tampermonkey.net/
// @version 1.1
// @description 为gmgn.ai网站的钱包地址添加Solscan跳转按钮,但在特定区域内不显示
// @author memeslayer
// @license MIT
// @match https://gmgn.ai/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 定义需要排除的区域选择器
const EXCLUDED_AREAS = [
'.g-table-body', // 交易活动表格
'.g-table-wrapper', // 表格包装器
'[style*="overflow: auto"]' // 包含overflow: auto的元素
];
// 检查元素是否在排除区域内
function isInExcludedArea(element) {
for (let selector of EXCLUDED_AREAS) {
if (element.closest(selector)) {
return true;
}
}
return false;
}
// 等待页面加载完成后执行
function addSolscanButtons() {
// 查找所有钱包地址链接
const walletLinks = document.querySelectorAll('a[href*="/sol/address/"]');
walletLinks.forEach(link => {
// 检查是否已经添加过按钮,避免重复添加
if (link.dataset.solscanProcessed) return;
// 检查是否在排除区域内
if (isInExcludedArea(link)) {
// 标记为已处理但不添加按钮
link.dataset.solscanProcessed = 'true';
return;
}
// 从href中提取钱包地址
const href = link.getAttribute('href');
const addressMatch = href.match(/\/sol\/address\/([A-Za-z0-9]+)/);
if (addressMatch) {
const walletAddress = addressMatch[1];
// 创建Solscan按钮
const solscanButton = createSolscanButton(walletAddress);
// 寻找合适的插入位置 - 在链接的父容器后面
const container = link.parentElement;
if (container) {
// 创建一个包装div来放置按钮
const buttonWrapper = document.createElement('div');
buttonWrapper.style.cssText = `
display: flex;
align-items: center;
margin-left: 6px;
`;
buttonWrapper.appendChild(solscanButton);
// 将按钮插入到链接后面
container.insertAdjacentElement('afterend', buttonWrapper);
}
// 标记为已处理
link.dataset.solscanProcessed = 'true';
}
});
}
// 创建Solscan按钮
function createSolscanButton(address) {
const button = document.createElement('button');
button.innerHTML = `
<svg width="10" height="10" viewBox="0 0 24 24" fill="currentColor">
<path d="M19 3H5C3.9 3 3 3.9 3 5V19C3 20.1 3.9 21 5 21H19C20.1 21 21 20.1 21 19V5C21 3.9 20.1 3 19 3ZM19 19H5V5H19V19Z"/>
<path d="M7 7H17V9H7V7ZM7 11H17V13H7V11ZM7 15H13V17H7V15Z"/>
</svg>
`;
button.title = `在Solscan中查看地址: ${address.substring(0, 8)}...`;
button.style.cssText = `
display: flex;
align-items: center;
justify-content: center;
padding: 3px;
background: linear-gradient(135deg, #5BACF8 0%, #4A9FE7 100%);
color: white;
border: none;
border-radius: 3px;
cursor: pointer;
transition: all 0.2s ease;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
z-index: 1000;
min-width: 16px;
min-height: 16px;
`;
// 鼠标悬停效果
button.addEventListener('mouseenter', () => {
button.style.background = 'linear-gradient(135deg, #4A9FE7 0%, #3B8ED6 100%)';
button.style.transform = 'translateY(-1px)';
button.style.boxShadow = '0 2px 6px rgba(0,0,0,0.15)';
});
button.addEventListener('mouseleave', () => {
button.style.background = 'linear-gradient(135deg, #5BACF8 0%, #4A9FE7 100%)';
button.style.transform = 'translateY(0)';
button.style.boxShadow = '0 1px 3px rgba(0,0,0,0.1)';
});
// 点击事件
button.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
// 构建Solscan URL
const solscanUrl = `https://solscan.io/account/${address}?activity_type=ACTIVITY_SPL_TRANSFER&remove_spam=true&exclude_amount_zero=true&flow=in&value=100&value=undefined&token_address=So11111111111111111111111111111111111111111#transfers`;
// 在新标签页中打开
window.open(solscanUrl, '_blank', 'noopener,noreferrer');
});
return button;
}
// 处理动态加载的内容
function setupObserver() {
const observer = new MutationObserver((mutations) => {
let shouldProcess = false;
mutations.forEach((mutation) => {
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
// 检查是否有新的钱包链接被添加
mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE) {
if (node.querySelector && node.querySelector('a[href*="/sol/address/"]')) {
shouldProcess = true;
}
}
});
}
});
if (shouldProcess) {
// 延迟执行以确保DOM完全更新
setTimeout(addSolscanButtons, 100);
}
});
// 开始观察
observer.observe(document.body, {
childList: true,
subtree: true
});
return observer;
}
// 等待页面加载完成
function init() {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => {
setTimeout(() => {
addSolscanButtons();
setupObserver();
}, 500);
});
} else {
setTimeout(() => {
addSolscanButtons();
setupObserver();
}, 500);
}
}
// 初始化脚本
init();
// 定期检查新的元素(备用方案)
setInterval(addSolscanButtons, 3000);
console.log('GMGN Solscan 跳转按钮已激活 - 已排除特定区域');
})();