// ==UserScript== // @name 网页复制限制解除 // @namespace http://tampermonkey.net/ // @version 1.4 // @description 解除网站复制限制、去除复制水印 // @author Heavrnl // @license MIT // @match *://*/* // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_addStyle // @downloadURL none // ==/UserScript== (function () { 'use strict'; // 检查是否在 iframe 中 const isInIframe = window !== window.top; // 添加设置界面的样式 GM_addStyle(` .watermark-settings { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.3); z-index: 10000; width: 500px; font-family: Arial, sans-serif; } .watermark-settings h2 { margin: 0 0 15px 0; color: #333; } .watermark-settings .buttons { display: flex; justify-content: flex-end; gap: 10px; } .watermark-settings button { padding: 8px 15px; border: none; border-radius: 4px; cursor: pointer; } .watermark-settings .save { background: #28a745; color: white; } .watermark-settings .cancel { background: #dc3545; color: white; } .watermark-settings .overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); z-index: 9999; } `); // 初始化设置 - 只在主页面中执行 if (!isInIframe) { if (GM_getValue('watermarkSites') === undefined) { GM_setValue('watermarkSites', {}); // 使用对象存储各网站的去水印状态 } if (GM_getValue('copySites') === undefined) { GM_setValue('copySites', {}); // 使用对象存储各网站的复制解除状态 } } // 检查当前网站的复制解除状态 const isCopyEnabled = () => { const currentHost = window.location.hostname; const copySites = GM_getValue('copySites', {}); return copySites[currentHost] || false; }; // 修改去水印功能 function removeWatermark() { const currentHost = window.location.hostname; const watermarkSites = GM_getValue('watermarkSites', {}); if (!watermarkSites[currentHost]) return; document.addEventListener('copy', function(e) { e.stopPropagation(); const selection = window.getSelection(); e.clipboardData.setData('text/plain', selection.toString()); e.preventDefault(); }, true); } // 创建并添加按钮 const button = document.createElement("button"); // 使用 SVG 图标替代文字 const svgIcon = ` `; button.innerHTML = svgIcon; // 根据存储的状态设置按钮样式 const isEnabled = GM_getValue('enableCopyRemoval', false); const getButtonStyle = (enabled) => ` position: fixed; right: 10px; bottom: 15%; z-index: 9999; width: 32px; height: 32px; padding: 6px; background-color: ${enabled ? 'rgba(220, 53, 69, 0.3)' : 'rgba(40, 167, 69, 0.3)'}; color: white; border: none; border-radius: 50%; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; opacity: 0.3; `; button.style.cssText = getButtonStyle(isEnabled); // 悬停效果 button.onmouseenter = () => { button.style.opacity = "1"; const currentHost = window.location.hostname; const copySites = GM_getValue('copySites', {}); const isEnabled = copySites[currentHost] || false; button.style.backgroundColor = isEnabled ? 'rgba(220, 53, 69, 0.9)' : 'rgba(40, 167, 69, 0.9)'; }; button.onmouseleave = () => { button.style.opacity = "0.3"; const currentHost = window.location.hostname; const copySites = GM_getValue('copySites', {}); const isEnabled = copySites[currentHost] || false; button.style.backgroundColor = isEnabled ? 'rgba(220, 53, 69, 0.3)' : 'rgba(40, 167, 69, 0.3)'; }; document.body.appendChild(button); // 修改点击按钮时切换状态的代码 const handleButtonClick = () => { const currentHost = window.location.hostname; const copySites = GM_getValue('copySites', {}); const currentState = copySites[currentHost] || false; if (!currentState) { // 启用当前网站的复制解除 copySites[currentHost] = true; GM_setValue('copySites', copySites); // 立即启用复制解除 enableCopyAndRemoveOverlay(); // 更新按钮样式 button.style.backgroundColor = 'rgba(220, 53, 69, 0.3)'; // 立即应用额外的复制解除措施 const style = document.createElement('style'); style.innerHTML = ` * { -webkit-user-select: text !important; -moz-user-select: text !important; -ms-user-select: text !important; user-select: text !important; -webkit-touch-callout: default !important; } ::selection { background-color: #338FFF !important; color: #fff !important; } `; document.head.appendChild(style); // 立即移除所有元素的复制限制 document.querySelectorAll('*').forEach(element => { element.style.userSelect = "text"; element.style.webkitUserSelect = "text"; element.style.msUserSelect = "text"; element.style.MozUserSelect = "text"; // 移除事件监听器 element.oncontextmenu = null; element.onselectstart = null; element.onselect = null; element.oncopy = null; element.onbeforecopy = null; element.oncut = null; element.onpaste = null; element.ondrag = null; element.ondragstart = null; }); // 立即覆盖文档级别的事件 document.oncontextmenu = null; document.onselectstart = null; document.oncopy = null; document.oncut = null; document.onpaste = null; // 添加复制事件监听器 document.addEventListener('copy', function(e) { e.stopPropagation(); const selection = window.getSelection(); e.clipboardData.setData('text/plain', selection.toString()); }, true); } else { // 禁用当前网站的复制解除 copySites[currentHost] = false; GM_setValue('copySites', copySites); location.reload(); // 刷新页面以恢复原始状态 } }; // 绑定点击事件 button.addEventListener("click", handleButtonClick); // 移除复制限制及遮挡层的功能 const enableCopyAndRemoveOverlay = () => { const currentHost = window.location.hostname; const copySites = GM_getValue('copySites', {}); if (!copySites[currentHost]) return; // 处理CSDN特定的复制限制 document.querySelectorAll('*').forEach(element => { // 移除CSDN特定的user-select限制 if (element.classList.contains('htmledit_views') || element.classList.contains('markdown_views') || element.classList.contains('article_content')) { element.style.cssText = ` -webkit-user-select: text !important; -moz-user-select: text !important; -ms-user-select: text !important; user-select: text !important; `; } // 移除CSDN的事件监听器 element.oncontextmenu = null; element.onselectstart = null; element.onselect = null; element.oncopy = null; element.onbeforecopy = null; element.oncut = null; element.onpaste = null; element.ondrag = null; element.ondragstart = null; }); // 覆盖CSDN的复制事件处理 document.addEventListener('copy', function(e) { e.stopPropagation(); const selection = window.getSelection(); e.clipboardData.setData('text/plain', selection.toString()); }, true); // 移除CSDN的遮罩层和弹窗 const removeOverlays = () => { const overlays = document.querySelectorAll('.login-mark, .login-box'); overlays.forEach(overlay => overlay.remove()); }; // 定期检查并移除遮罩 setInterval(removeOverlays, 100); // 移除所有元素的复制限制 document.querySelectorAll('*').forEach(element => { // 允许选择文本 element.style.userSelect = "text"; element.style.webkitUserSelect = "text"; element.style.msUserSelect = "text"; element.style.MozUserSelect = "text"; // 移除事件监听器 element.onselectstart = null; element.oncontextmenu = null; element.onmousedown = null; element.onkeydown = null; element.oncopy = null; element.oncut = null; element.ondrag = null; element.ondragstart = null; // 移除 unselectable 属性 element.removeAttribute('unselectable'); element.removeAttribute('oncontextmenu'); element.removeAttribute('oncopy'); element.removeAttribute('oncut'); element.removeAttribute('onselectstart'); }); // 移除遮挡层 document.querySelectorAll('*').forEach(element => { const style = window.getComputedStyle(element); if ((style.position === 'absolute' || style.position === 'fixed') && (style.opacity === '0' || parseFloat(style.opacity) < 0.1) && style.zIndex > 0) { element.remove(); } }); // 覆盖常见的禁用右键和复制的方法 document.oncontextmenu = null; document.onselectstart = null; document.oncopy = null; document.oncut = null; document.onpaste = null; document.onkeydown = null; document.onmousedown = null; // 覆盖 window 对象上的限制方法 window.oncontextmenu = null; window.onselectstart = null; window.oncopy = null; window.oncut = null; window.onpaste = null; window.onkeydown = null; window.onmousedown = null; // 阻止页面使用 addEventListener 添加新的限制 const originalAddEventListener = EventTarget.prototype.addEventListener; EventTarget.prototype.addEventListener = function(type, listener, options) { if (type === 'contextmenu' || type === 'selectstart' || type === 'copy' || type === 'cut' || type === 'paste' || type === 'keydown' || type === 'mousedown') { return; } originalAddEventListener.call(this, type, listener, options); }; // 移除 CSS 限制 const style = document.createElement('style'); style.innerHTML = ` * { -webkit-user-select: text !important; -moz-user-select: text !important; -ms-user-select: text !important; user-select: text !important; -webkit-touch-callout: default !important; } ::selection { background-color: #338FFF !important; color: #fff !important; } `; document.head.appendChild(style); }; // 修改 MutationObserver,只在功能开启时才观察 const observer = new MutationObserver(() => { if (GM_getValue('enableCopyRemoval', false)) { enableCopyAndRemoveOverlay(); } }); observer.observe(document.body, { childList: true, subtree: true }); // 创建并添加去水印按钮 const watermarkButton = document.createElement("button"); const watermarkSvgIcon = ` `; watermarkButton.innerHTML = watermarkSvgIcon; // 获取去水印功能的状态 const isWatermarkEnabled = () => { const currentHost = window.location.hostname; const watermarkSites = GM_getValue('watermarkSites', {}); return watermarkSites[currentHost] || false; }; // 设置去水印按钮样式 const getWatermarkButtonStyle = (enabled) => ` position: fixed; right: 10px; bottom: 10%; z-index: 9999; width: 32px; height: 32px; padding: 6px; background-color: ${enabled ? 'rgba(220, 53, 69, 0.3)' : 'rgba(40, 167, 69, 0.3)'}; color: white; border: none; border-radius: 50%; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; opacity: 0.3; `; watermarkButton.style.cssText = getWatermarkButtonStyle(isWatermarkEnabled()); // 去水印按钮的悬停效果 watermarkButton.onmouseenter = () => { watermarkButton.style.opacity = "1"; const currentHost = window.location.hostname; const watermarkSites = GM_getValue('watermarkSites', {}); const isEnabled = watermarkSites[currentHost] || false; watermarkButton.style.backgroundColor = isEnabled ? 'rgba(220, 53, 69, 0.9)' : 'rgba(40, 167, 69, 0.9)'; }; watermarkButton.onmouseleave = () => { watermarkButton.style.opacity = "0.3"; const currentHost = window.location.hostname; const watermarkSites = GM_getValue('watermarkSites', {}); const isEnabled = watermarkSites[currentHost] || false; watermarkButton.style.backgroundColor = isEnabled ? 'rgba(220, 53, 69, 0.3)' : 'rgba(40, 167, 69, 0.3)'; }; // 去水印按钮点击事件 watermarkButton.addEventListener("click", () => { const currentHost = window.location.hostname; const watermarkSites = GM_getValue('watermarkSites', {}); const currentState = watermarkSites[currentHost] || false; watermarkSites[currentHost] = !currentState; GM_setValue('watermarkSites', watermarkSites); // 立即应用新状态 if (!currentState) { removeWatermark(); } else { location.reload(); // 如果是关闭状态,需要刷新页面 } // 更新按钮样式 watermarkButton.style.cssText = getWatermarkButtonStyle(!currentState); }); document.body.appendChild(watermarkButton); // 添加按钮组样式 GM_addStyle(` .float-button-group { position: fixed; right: 10px; bottom: 15%; z-index: 9999; display: flex; flex-direction: column; gap: 8px; } .float-button { width: 32px; height: 32px; padding: 6px; background-color: rgba(40, 167, 69, 0.3); color: white; border: none; border-radius: 50%; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; opacity: 0.3; } `); // 创建按钮组容器 const buttonGroup = document.createElement('div'); buttonGroup.className = 'float-button-group'; // 创建复制解除按钮 const copyButton = document.createElement("button"); copyButton.className = 'float-button'; copyButton.innerHTML = svgIcon; // 创建去水印按钮 const watermarkBtn = document.createElement("button"); watermarkBtn.className = 'float-button'; watermarkBtn.innerHTML = watermarkSvgIcon; // 更新按钮状态的函数 const updateButtonStyle = (btn, enabled) => { btn.style.backgroundColor = enabled ? 'rgba(220, 53, 69, 0.3)' : 'rgba(40, 167, 69, 0.3)'; }; // 设置初始状态 const copyEnabled = isCopyEnabled(); updateButtonStyle(copyButton, copyEnabled); const watermarkEnabled = isWatermarkEnabled(); updateButtonStyle(watermarkBtn, watermarkEnabled); // 复制按钮的悬停效果 copyButton.onmouseenter = () => { copyButton.style.opacity = "1"; const isEnabled = isCopyEnabled(); copyButton.style.backgroundColor = isEnabled ? 'rgba(220, 53, 69, 0.9)' : 'rgba(40, 167, 69, 0.9)'; }; copyButton.onmouseleave = () => { copyButton.style.opacity = "0.3"; const isEnabled = isCopyEnabled(); copyButton.style.backgroundColor = isEnabled ? 'rgba(220, 53, 69, 0.3)' : 'rgba(40, 167, 69, 0.3)'; }; // 去水印按钮的悬停效果 watermarkBtn.onmouseenter = () => { watermarkBtn.style.opacity = "1"; const currentHost = window.location.hostname; const watermarkSites = GM_getValue('watermarkSites', {}); const isEnabled = watermarkSites[currentHost] || false; watermarkBtn.style.backgroundColor = isEnabled ? 'rgba(220, 53, 69, 0.9)' : 'rgba(40, 167, 69, 0.9)'; }; watermarkBtn.onmouseleave = () => { watermarkBtn.style.opacity = "0.3"; const currentHost = window.location.hostname; const watermarkSites = GM_getValue('watermarkSites', {}); const isEnabled = watermarkSites[currentHost] || false; watermarkBtn.style.backgroundColor = isEnabled ? 'rgba(220, 53, 69, 0.3)' : 'rgba(40, 167, 69, 0.3)'; }; // 绑定点击事件 copyButton.addEventListener("click", handleButtonClick); watermarkBtn.addEventListener("click", handleWatermarkButtonClick); // 将按钮添加到按钮组 buttonGroup.appendChild(copyButton); buttonGroup.appendChild(watermarkBtn); // 将按钮组添加到页面 document.body.appendChild(buttonGroup); // 移除之前直接添加到body的按钮 const oldButtons = document.querySelectorAll('button[style*="position: fixed"]'); oldButtons.forEach(btn => btn.remove()); })();