Query the homepage links of users on different social media platforms
// ==UserScript==
// @name 一键多平台搜索
// @name:zh-CN 一键多平台搜索
// @name:en Onekey Multiplatform Search
// @description 一键查询「用户名」在不同社交平台的主页链接,一键查询「视频标题」在不同平台的链接。
// @description:zh-CN 一键查询「用户名」在不同社交平台的主页链接,一键查询「视频标题」在不同平台的链接。
// @description:en Query the homepage links of users on different social media platforms
// @namespace https://www.runningcheese.com/userscripts
// @author RunningCheese
// @version 2.0
// @match https://space.bilibili.com/*
// @match https://*.weibo.com/u/*
// @match https://www.weibo.com/*
// @match https://www.zhihu.com/people/*
// @match https://www.douyin.com/user/*
// @match https://www.douban.com/people/*
// @match https://www.xiaohongshu.com/user/profile/*
// @match https://mp.weixin.qq.com/s*
// @match https://www.toutiao.com/c/user/*
// @match https://tieba.baidu.com/f?kw=*
// @match https://www.tiktok.com/@*
// @match https://x.com/*
// @match https://www.youtube.com/@*
// @match https://www.reddit.com/user/*
// @match https://www.bilibili.com/video/*
// @match https://www.youtube.com/watch*
// @match https://www.douyin.com/video/*
// @match https://www.tiktok.com/@*/video/*
// @match https://www.pinterest.com/*/*
// @match https://github.com/*
// @match https://www.threads.com/*
// @match https://www.facebook.com/*/
// @match https://www.instagram.com/*
// @grant none
// @license MIT
// @icon data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB2aWV3Qm94PSIwIDAgMTIwMCAxMjAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxwYXRoIGQ9Ik0wIDBoMTIwMHYxMjAwSDB6IiBmaWxsPSJub25lIiB0cmFuc2Zvcm09Im1hdHJpeCgxLCAwLCAwLCAxLCAyLjI3MzczNjc1NDQzMjMyMDZlLTEzLCAwKSIvPgogIDxwYXRoIGZpbGw9IiMyNzdiZTAiIGQ9Ik0gNjAwIDEyMDAgQyAyNjguNjI5IDEyMDAgMCA5MzEuMzcxIDAgNjAwIEMgMCAyNjguNjI5IDI2OC42MjkgMCA2MDAgMCBDIDkzMS4zNzEgMCAxMjAwIDI2OC42MjkgMTIwMCA2MDAgQyAxMjAwIDkzMS4zNzEgOTMxLjM3MSAxMjAwIDYwMCAxMjAwIE0gNjQxLjE2MiA5MzkuOTkgQyA4MDEuNjk1IDkzOS45OSA5MzEuNzg3IDgwOS44MjQgOTMxLjc4NyA2NDkuMjkyIEMgOTMxLjc4NyA0ODguNzU5IDgwMS42OTUgMzU4LjY2NyA2NDEuMTYyIDM1OC42NjcgQyA1OTIuNTgxIDM1OC42NjcgNTQ2Ljc5NCAzNzAuNTUyIDUwNi41NDMgMzkxLjYyNiBDIDUwNi41ODQgMzkxLjQ0IDUwNi42NDkgMzkxLjIyNSA1MDYuNjg5IDM5MS4wNCBMIDM3NS41ODYgMjYwLjAxIEwgMjY4LjIxMyAzNjcuNDU2IEwgMzk0LjYyOSA0OTMuOTQ1IEMgMzk0LjgzOCA0OTQuMDM5IDM5NS4wNzkgNDk0LjA3NCAzOTUuMjg4IDQ5NC4xNjUgQyAzNjYuOTAxIDUzOS4wNTggMzUwLjQ2NCA1OTIuMjUzIDM1MC40NjQgNjQ5LjI5MiBDIDM1MC40NjQgODA5LjgyNSA0ODAuNjI5IDkzOS45OSA2NDEuMTYyIDkzOS45OSBNIDY0MS4xNjIgODEwLjg2NCBDIDU1MS45NDkgODEwLjg2NCA0NzkuNTkgNzM4LjUwNSA0NzkuNTkgNjQ5LjI5MiBDIDQ3OS41OSA1NjAuMDc5IDU1MS45NDkgNDg3Ljc5MyA2NDEuMTYyIDQ4Ny43OTMgQyA3MzAuMzc1IDQ4Ny43OTMgODAyLjY2MSA1NjAuMDc5IDgwMi42NjEgNjQ5LjI5MiBDIDgwMi42NjEgNzM4LjUwNSA3MzAuMzc2IDgxMC44NjQgNjQxLjE2MiA4MTAuODY0IiBzdHlsZT0idHJhbnNmb3JtLW9yaWdpbjogNjAwcHggNjAwcHg7IiB0cmFuc2Zvcm09Im1hdHJpeCgtMSwgMCwgMCwgLTEsIDAsIDApIi8+Cjwvc3ZnPg==
// ==/UserScript==
(function() {
'use strict';
// 平台用户名选择器映射
const platformSelectors = {
'space.bilibili.com': 'div[class*="nickname"]',
'weibo.com/u/': 'div._name_1yc79_291',
'www.weibo.com/': 'div._name_1yc79_291',
'zhihu.com/people/': '.ProfileHeader-name',
'douyin.com/user': [
'[data-e2e="user-info"] h1',
'[data-e2e="user-title"]',
'h1[class*="name"]',
'.arnSiSbK'
],
'xiaohongshu.com/user': 'div[class*="user-name"], .user-name',
'tieba.baidu.com/f?kw': '.card_title_fname',
'douban.com/people/': '.info h1',
'mp.weixin.qq.com/s': ['#js_name', '#js_ip_wording', '#publish_time'],
'toutiao.com/c/user/': '.name',
'tiktok.com/@': 'h1[data-e2e="user-title"]',
'x.com/': 'div[data-testid="UserName"]',
'twitter.com/': 'div[data-testid="UserName"]',
'facebook.com/': '.html-h1',
'instagram.com': [
'header h2',
'h2[class*="x"]',
'section h2'
],
'reddit.com/user/': 'h1[class*="Header__username"]',
'threads.com/@': '.xcrlgei h1',
'github.com/': '.p-name.vcard-fullname',
'youtube.com': [
'h1.dynamicTextViewModelH1',
'yt-dynamic-text-view-model[class*="ytPageHeaderViewModelTitle"] h1',
'#page-header yt-dynamic-text-view-model h1',
'#channel-name yt-formatted-string:not([is-empty])',
'#text-container yt-formatted-string:not([is-empty])',
'.yt-core-attributed-string--white-space-pre-wrap',
'#channel-name #text',
'#channel-header-container h1',
'#channel-title'
]
};
// 视频标题选择器映射
const videoTitleSelectors = {
'bilibili.com/video/': [
'h1.video-title',
'.video-title',
'h1[class*="video-title"]',
'.video-title > .tit'
],
'youtube.com/watch': [
'h1.ytd-watch-metadata yt-formatted-string',
'#title h1',
'h1.style-scope.ytd-watch-metadata'
],
'douyin.com/video/': [
'.video-info-detail .title',
'h1[class*="title"]',
'[data-e2e="video-desc"]'
],
'tiktok.com/video/': [
'h1[data-e2e="video-desc"]',
'h1[class*="title"]'
]
};
// 创建浮动窗口
const panel = document.createElement('div');
panel.id = 'social-query-panel';
panel.style.cssText = 'position:fixed;top:12%;left:45%;background:#fff;border:none;border-radius:8px;padding:4px;width:300px;box-shadow:0 4px 12px rgba(0,0,0,0.25);z-index:999999;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;display:none;';
// 增强样式隔离性
const styleElement = document.createElement('style');
styleElement.textContent = `
#social-query-panel input[type="checkbox"] {
appearance: auto !important;
}
.social-query-icon {
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
width: 18px;
height: 18px;
border-radius: 4px;
cursor: pointer;
margin-left: 10px;
vertical-align: middle;
transition: background-color 0.3s;
flex-shrink: 0;
color: white;
background-color: #277BE0;
box-sizing: content-box;
line-height: 1;
overflow: visible !important;
}
.social-query-icon svg {
display: block !important;
width: 14px;
height: 14px;
fill: currentColor;
flex-shrink: 0;
pointer-events: none;
}
.social-query-icon:hover {
background-color: #0088ff;
transform: scale(1.1);
}
.sq-btn {
flex: 1;
padding: 5px 12px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 13px;
font-family: inherit;
transition: background 0.15s;
text-align: center;
}
.sq-btn-default {
background: #e5e5ea;
color: #333;
}
.sq-btn-default:hover {
background: #d1d1d6;
}
.sq-btn-primary {
background: #007aff;
color: #fff;
}
.sq-btn-primary:hover {
background: #0062cc;
}
`;
document.head.appendChild(styleElement);
// 当前模式:'username' 或 'title'
let currentMode = 'username';
// 创建放大镜图标
function createMagnifierIcon() {
const icon = document.createElement('span');
icon.className = 'social-query-icon';
icon.title = '多平台搜索';
icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="currentColor"><circle cx="6.5" cy="6.5" r="5" fill="none" stroke="currentColor" stroke-width="2.5"/><path d="M10.5 10.5l1.5 2" stroke="currentColor" stroke-width="3" stroke-linecap="round"/></svg>';
icon.addEventListener('click', function(e) {
e.stopPropagation();
panel.style.display = 'block';
contentContainer.style.display = 'block';
const rect = icon.getBoundingClientRect();
panel.style.top = (rect.bottom + window.scrollY + 10) + 'px';
panel.style.left = (rect.left + window.scrollX - 150) + 'px';
setTimeout(() => inputField.focus(), 100);
});
return icon;
}
// 根据不同平台添加交互(用户名页面显示图标,视频页面双击标题)
function addMagnifierIcon() {
const currentURL = window.location.href;
let targetElement = null;
let targetText = '';
let detectedMode = 'username';
// 1. 先检查是否为视频页面(视频标题选择器)
for (const [urlPart, selector] of Object.entries(videoTitleSelectors)) {
if (currentURL.includes(urlPart)) {
detectedMode = 'title';
const selectors = Array.isArray(selector) ? selector : [selector];
for (const sel of selectors) {
const element = document.querySelector(sel);
if (element && element.textContent.trim()) {
targetElement = element;
targetText = element.textContent.trim();
break;
}
}
if (targetElement) break;
}
}
// 2. 如果不是视频页面,退回到用户名选择器(原有逻辑)
if (!targetElement) {
for (const [urlPart, selector] of Object.entries(platformSelectors)) {
if (currentURL.includes(urlPart)) {
if (Array.isArray(selector)) {
for (const sel of selector) {
const element = document.querySelector(sel);
if (element && element.textContent.trim()) {
if (urlPart === 'mp.weixin.qq.com/s') {
if (sel === '#js_name') {
targetText = element.textContent.trim();
} else if (sel === '#js_ip_wording') {
targetElement = element;
} else if (sel === '#publish_time' && !targetElement) {
targetElement = element;
}
} else {
targetElement = element;
break;
}
}
}
if (targetText && !targetElement) {
targetElement = document.querySelector('#js_ip_wording') || document.querySelector('#publish_time');
}
} else {
targetElement = document.querySelector(selector);
}
break;
}
}
}
// 3. 如果找到目标元素
if (targetElement) {
if (detectedMode === 'title') {
// 视频页面:添加双击事件
if (targetElement.dataset.socialQueryBound) return;
targetElement.dataset.socialQueryBound = 'true';
targetElement.addEventListener('dblclick', function(e) {
e.stopPropagation();
panel.style.display = 'block';
contentContainer.style.display = 'block';
// 面板出现在鼠标位置下方,自适应边界
const panelW = panel.offsetWidth || 300;
const panelH = panel.offsetHeight || 400;
let top = e.clientY + 10;
let left = e.clientX - Math.round(panelW / 2);
if (top + panelH > window.innerHeight) top = window.innerHeight - panelH - 10;
if (left + panelW > window.innerWidth) left = window.innerWidth - panelW - 10;
if (left < 10) left = 10;
panel.style.top = top + 'px';
panel.style.left = left + 'px';
// 自动填充文本
inputField.value = targetText || targetElement.textContent.trim();
currentMode = detectedMode;
inputField.placeholder = '输入要搜索的视频标题';
setTimeout(() => inputField.focus(), 100);
});
} else {
// 用户名页面:插入图标
if (targetElement.querySelector('.social-query-icon')) return;
const icon = createMagnifierIcon();
if (currentURL.includes('douyin.com') || currentURL.includes('instagram.com')) {
targetElement.style.display = 'inline-flex';
targetElement.style.alignItems = 'center';
}
// 追加到标题文本之后
// 防止父元素 text-overflow/overflow 导致图标显示为 ... 或被裁切
const parentStyle = getComputedStyle(targetElement);
if (parentStyle.textOverflow === 'ellipsis') {
targetElement.style.setProperty('text-overflow', 'clip', 'important');
}
if (parentStyle.overflow === 'hidden') {
targetElement.style.overflow = 'visible';
}
targetElement.appendChild(icon);
// 将无文本的第三方图标移到本图标后面
const allChildren = Array.from(targetElement.children);
const myIdx = allChildren.indexOf(icon);
for (let i = 0; i < myIdx; i++) {
const el = allChildren[i];
if (el.tagName === 'SPAN' || el.tagName === 'A' || el.tagName === 'IMG') {
if (!(el.textContent || '').trim()) {
targetElement.appendChild(el);
}
}
}
}
// 自动填充文本
inputField.value = targetText || targetElement.textContent.trim();
currentMode = detectedMode;
inputField.placeholder = detectedMode === 'title' ? '输入要搜索的视频标题' : '输入要查询的用户名';
}
}
// 创建标题栏
const titleBar = document.createElement('div');
titleBar.style.cssText = 'display:flex;justify-content:space-between;align-items:center;padding:4px 10px;font-size:14px;color:#333;border-bottom:1px solid #eee;margin-bottom:4px;cursor:move;border-radius:8px 8px 0 0;';
// 创建标题文本
const titleText = document.createElement('span');
titleText.textContent = '▼ 一键多平台搜索';
titleText.style.cssText = 'flex:1;';
titleBar.appendChild(titleText);
// 创建关闭按钮
const closeBtn = document.createElement('span');
closeBtn.textContent = '\u2715';
closeBtn.style.cssText = 'cursor:pointer;color:#999;width:20px;height:20px;display:flex;align-items:center;justify-content:center;border-radius:50%;transition:all 0.2s ease;margin-left:10px;';
closeBtn.addEventListener('mouseover', () => closeBtn.style.backgroundColor = '#dadada');
closeBtn.addEventListener('mouseout', () => closeBtn.style.backgroundColor = '');
closeBtn.addEventListener('click', (e) => {
e.stopPropagation();
panel.style.display = 'none';
});
titleBar.appendChild(closeBtn);
// 创建内容容器
const contentContainer = document.createElement('div');
contentContainer.style.cssText = 'display:block;'; // 默认展开
// 拖动相关变量和事件
let startX = 0, startY = 0, startLeft = 0, startTop = 0, isDragging = false;
titleBar.addEventListener('mousedown', function(e) {
if (e.target === closeBtn) return;
isDragging = true;
startX = e.clientX;
startY = e.clientY;
startLeft = parseInt(window.getComputedStyle(panel).left);
startTop = parseInt(window.getComputedStyle(panel).top);
e.preventDefault();
});
function mouseMoveHandler(e) {
if (!isDragging) return;
const deltaX = e.clientX - startX;
const deltaY = e.clientY - startY;
panel.style.left = (startLeft + deltaX) + 'px';
panel.style.top = (startTop + deltaY) + 'px';
}
function mouseUpHandler() {
isDragging = false;
}
document.addEventListener('mousemove', mouseMoveHandler);
document.addEventListener('mouseup', mouseUpHandler);
// 双击Esc关闭窗口
let lastEscTime = 0;
function escHandler(evt) {
if (evt.key === 'Escape') {
const now = Date.now();
if (now - lastEscTime <= 300) {
panel.style.display = 'none';
}
lastEscTime = now;
}
}
document.addEventListener('keydown', escHandler);
// 创建输入框
const inputContainer = document.createElement('div');
inputContainer.style.cssText = 'padding:8px 10px;display:flex;align-items:center;';
const inputField = document.createElement('input');
inputField.style.cssText = 'flex:1;padding:4px 8px;border:1px solid #ccc;border-radius:4px;font-size:14px;width:100%;';
inputField.placeholder = '输入要查询的用户名';
inputContainer.appendChild(inputField);
// 社交平台列表
const chinesePlatforms = [
{title: '微博', url: 'https://s.weibo.com/weibo/'},
{title: '抖音', url: 'https://www.douyin.com/search/'},
{title: '哔哩哔哩', url: 'https://search.bilibili.com/all?keyword='},
{title: '小红书', url: 'https://www.xiaohongshu.com/search_result?keyword='},
{title: '知乎', url: 'https://www.zhihu.com/search?q='},
{title: '豆瓣', url: 'https://www.douban.com/search?cat=1005&q='},
{title: '公众号', url: 'https://weixin.sogou.com/weixin?type=2&query='},
{title: '头条', url: 'https://so.toutiao.com/search?dvpf=pc&source=input&keyword='},
{title: '贴吧', url: 'https://tieba.baidu.com/f?kw='}
];
const foreignPlatforms = [
{title: 'Twitter', url: 'https://x.com/search?q='},
{title: 'TikTok', url: 'https://www.tiktok.com/search/user?q='},
{title: 'YouTube', url: 'https://www.youtube.com/results?search_query='},
{title: 'Instagram', url: 'https://www.instagram.com/explore/search/keyword/?q='},
{title: 'Facebook', url: 'https://www.facebook.com/search/top/?q='},
{title: 'Pinterest', url: 'https://www.pinterest.com/search/pins/?q='},
{title: 'GitHub', url: 'https://github.com/search?type=users&q='},
{title: 'Reddit', url: 'https://www.reddit.com/search/?q='},
{title: 'Threads', url: 'https://www.threads.com/search?q='}
];
// 创建平台容器
const platformContainer = document.createElement('div');
platformContainer.style.cssText = 'display:flex;flex-wrap:wrap;padding:10px;';
// 添加复选框
function createCheckboxItem(platform, container, isDefault = false) {
const item = document.createElement('div');
item.style.cssText = 'width:33.33%;padding:5px 5px 5px 1px;box-sizing:border-box;';
const label = document.createElement('label');
label.style.cssText = 'display:flex;align-items:center;font-size:14px;cursor:pointer;color:#333;white-space:nowrap;';
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.dataset.url = platform.url;
checkbox.style.marginRight = '5px';
checkbox.checked = isDefault;
// 阻止事件冒泡
checkbox.addEventListener('mousedown', e => e.stopPropagation());
label.addEventListener('mousedown', e => e.stopPropagation());
label.appendChild(checkbox);
label.appendChild(document.createTextNode(platform.title));
item.appendChild(label);
container.appendChild(item);
}
// 合并所有平台到同一个容器
const allPlatforms = [...chinesePlatforms, ...foreignPlatforms];
allPlatforms.forEach(platform => {
const isDefault = ['哔哩哔哩', '微博', '抖音'].includes(platform.title);
createCheckboxItem(platform, platformContainer, isDefault);
});
// 添加按钮区域
const buttonContainer = document.createElement('div');
buttonContainer.style.cssText = 'display:flex;gap:8px;padding:12px 8px 8px 8px;border-top:1px solid #eee;font-size:14px;';
// 创建按钮函数
function createButton(text, className, clickHandler) {
const button = document.createElement('button');
button.textContent = text;
button.className = className;
button.addEventListener('mousedown', e => e.stopPropagation());
button.addEventListener('click', clickHandler);
return button;
}
// 全选按钮
const selectAllBtn = createButton(
'全选',
'sq-btn sq-btn-default',
e => {
e.stopPropagation();
panel.querySelectorAll('input[type="checkbox"]').forEach(cb => cb.checked = true);
}
);
// 取消全选按钮
const deselectAllBtn = createButton(
'取消',
'sq-btn sq-btn-default',
e => {
e.stopPropagation();
panel.querySelectorAll('input[type="checkbox"]').forEach(cb => cb.checked = false);
}
);
// 查询按钮
const queryBtn = createButton(
'查询',
'sq-btn sq-btn-primary',
e => {
e.stopPropagation();
const username = inputField.value.trim();
if (!username) {
alert(currentMode === 'title' ? '请输入视频标题' : '请输入用户名');
return;
}
const selectedCheckboxes = panel.querySelectorAll('input[type="checkbox"]:checked');
if (selectedCheckboxes.length === 0) {
alert('请至少选择一个平台');
return;
}
// 打开选中的平台
selectedCheckboxes.forEach(checkbox => {
window.open(checkbox.dataset.url + username);
});
}
);
buttonContainer.appendChild(selectAllBtn);
buttonContainer.appendChild(deselectAllBtn);
buttonContainer.appendChild(queryBtn);
// 将所有内容添加到内容容器
contentContainer.appendChild(inputContainer);
contentContainer.appendChild(platformContainer);
contentContainer.appendChild(buttonContainer);
// 组装面板
panel.appendChild(titleBar);
panel.appendChild(contentContainer);
// 添加到页面
document.body.appendChild(panel);
// 添加点击页面其他区域关闭面板
document.addEventListener('click', function(e) {
if (!panel.contains(e.target) && !e.target.classList.contains('social-query-icon')) {
panel.style.display = 'none';
}
});
// 添加放大镜图标 — 第一时间尝试
addMagnifierIcon();
// DOM 就绪后再次尝试
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', addMagnifierIcon);
}
// 监听DOM变化,确保在动态加载的页面上也能添加图标
let iconAddPending = false;
const observer = new MutationObserver(function() {
if (iconAddPending) return;
iconAddPending = true;
requestAnimationFrame(function() {
addMagnifierIcon();
iconAddPending = false;
});
});
observer.observe(document.body, { childList: true, subtree: true });
})();