您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
hover 和按键追加 eagle-tags,英文逗号隔开,去重添加,标签配置持久化存储,支持Alt键批量添加+节流防抖
当前为
// ==UserScript== // @name eagle tagger | 区分不同浏览器身份,添加不同的 tag // @namespace http://leizingyiu.net/ // @version 20250511 // @description hover 和按键追加 eagle-tags,英文逗号隔开,去重添加,标签配置持久化存储,支持Alt键批量添加+节流防抖 // @author leizingyiu // @match *://*/* // @grant GM_getValue // @grant GM_setValue // @license GNU AGPLv3 // ==/UserScript== (function() { 'use strict'; const defaultBrowserTags = "browser-A,browser-B,browser-C"; const defaultTagsDict = { a: "tagA", b: "tagB", c: "tagC" }; function getBrowserTags() { let tags = GM_getValue('thisBrowserTags', defaultBrowserTags); return tags.replace(/,/g, ','); } function getTagsDict() { let dictStr = GM_getValue('tagsDict', JSON.stringify(defaultTagsDict)); try { let dict = JSON.parse(dictStr); return dict; } catch (e) { console.error('tagsDict 格式错误,已重置默认值'); GM_setValue('tagsDict', JSON.stringify(defaultTagsDict)); return defaultTagsDict; } } function addTagsToItem(item, tags) { if (!item) return; let oriTag = item.getAttribute('eagle-tags') || ''; let oriTagList = oriTag.split(',') .map(tag => tag.trim()) .filter(tag => tag.length > 0); let addTagList = Array.isArray(tags) ? tags : tags.replace(/,/g, ',') .split(',') .map(tag => tag.trim()) .filter(tag => tag.length > 0); addTagList.forEach(tag => { if (!oriTagList.includes(tag)) { oriTagList.push(tag); } }); item.setAttribute('eagle-tags', oriTagList.join(', ')); console.log('已更新 eagle-tags:', item.getAttribute('eagle-tags')); } function debounce(func, delay) { let timer; return function(...args) { clearTimeout(timer); timer = setTimeout(() => { func.apply(this, args); }, delay); }; } function throttle(func, limit) { let inThrottle; return function(...args) { if (!inThrottle) { func.apply(this, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; } let currentHoverItem = null; function addHoverListeners() { document.querySelectorAll('img, video').forEach(item => { if (item.hasAttribute('data-hover-tagged')) return; item.setAttribute('data-hover-tagged', 'true'); item.addEventListener('mouseenter', debounce(function() { currentHoverItem = item; addTagsToItem(item, getBrowserTags()); }, 200)); item.addEventListener('mouseleave', function() { if (currentHoverItem === item) { currentHoverItem = null; } }); }); } addHoverListeners(); const observer = new MutationObserver((mutationsList) => { for (let mutation of mutationsList) { if (mutation.type === 'childList') { addHoverListeners(); } } }); observer.observe(document.body, { childList: true, subtree: true }); window.addEventListener('keydown', throttle(function(e) { const key = e.code.replace('Key','').toLowerCase(); const tagsDict = getTagsDict(); if (tagsDict[key] && currentHoverItem) { addTagsToItem(currentHoverItem, tagsDict[key]); } if (e.altKey && tagsDict[key]) { document.querySelectorAll('img, video').forEach(item => { addTagsToItem(item, tagsDict[key]); }); } }, 200)); })();