您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Allows highlighting and copying text on websites where it might be disabled by overriding CSS and removing common disabling attributes.
// ==UserScript== // @name CopyAnything // @namespace http://tampermonkey.net/ // @version 1.0 // @description Allows highlighting and copying text on websites where it might be disabled by overriding CSS and removing common disabling attributes. // @author Aditya Mendiratta // @match *://*/* // @license MIT // @grant none // ==/UserScript== (function() { 'use strict'; function applyCssOverrides() { const style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = ` * { -webkit-user-select: text !important; -moz-user-select: text !important; -ms-user-select: text !important; user-select: text !important; } body { -webkit-user-select: text !important; -moz-user-select: text !important; -ms-user-select: text !important; user-select: text !important; } input, textarea { /* Ensure input fields are always selectable, though 'text' should generally cover this too. */ user-select: auto !important; } `; document.head.appendChild(style); console.log('User select CSS overrides applied.'); } function removeDisablingAttributes() { const elements = document.querySelectorAll('*'); let removedCount = 0; elements.forEach(el => { if (el.hasAttribute('onselectstart')) { el.removeAttribute('onselectstart'); removedCount++; } if (el.hasAttribute('ondragstart')) { el.removeAttribute('ondragstart'); removedCount++; } if (el.hasAttribute('oncontextmenu')) { el.removeAttribute('oncontextmenu'); removedCount++; } }); if (removedCount > 0) { console.log(`Removed ${removedCount} disabling attributes.`); } } const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.type === 'attributes' && (mutation.attributeName === 'onselectstart' || mutation.attributeName === 'ondragstart' || mutation.attributeName === 'oncontextmenu')) { if (mutation.target.hasAttribute('onselectstart')) { mutation.target.removeAttribute('onselectstart'); } if (mutation.target.hasAttribute('ondragstart')) { mutation.target.removeAttribute('ondragstart'); } if (mutation.target.hasAttribute('oncontextmenu')) { mutation.target.removeAttribute('oncontextmenu'); } } else if (mutation.type === 'childList') { mutation.addedNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE) { node.style.setProperty('-webkit-user-select', 'text', 'important'); node.style.setProperty('-moz-user-select', 'text', 'important'); node.style.setProperty('-ms-user-select', 'text', 'important'); node.style.setProperty('user-select', 'text', 'important'); if (node.hasAttribute('onselectstart')) { node.removeAttribute('onselectstart'); } if (node.hasAttribute('ondragstart')) { node.removeAttribute('ondragstart'); } if (node.hasAttribute('oncontextmenu')) { node.removeAttribute('oncontextmenu'); } node.querySelectorAll('*').forEach(descendant => { if (descendant.hasAttribute('onselectstart')) { descendant.removeAttribute('onselectstart'); } if (descendant.hasAttribute('ondragstart')) { descendant.removeAttribute('ondragstart'); } if (descendant.hasAttribute('oncontextmenu')) { descendant.removeAttribute('oncontextmenu'); } }); } }); } }); }); window.addEventListener('DOMContentLoaded', () => { applyCssOverrides(); removeDisablingAttributes(); observer.observe(document.body, { attributes: true, childList: true, subtree: true }); console.log('MutationObserver started for dynamic content.'); }); window.addEventListener('load', () => { applyCssOverrides(); removeDisablingAttributes(); }); })();