Greasy Fork is available in English.
移除网页对复制、粘贴、右键、选中、切屏检测(onblur / visibilitychange)的限制,支持 iframe 与 Shadow DOM 深层拦截。
当前为
// ==UserScript==
// @name 解锁网页复制/粘贴/右键/切屏限制💉
// @namespace http://greasyfork.icu/zh-CN/users/1534803-ookamiame
// @version 1.0
// @description 移除网页对复制、粘贴、右键、选中、切屏检测(onblur / visibilitychange)的限制,支持 iframe 与 Shadow DOM 深层拦截。
// @author 狼小雨
// @license MIT
// @match *://*/*
// @grant none
// @run-at document-start
// ==/UserScript==
(function () {
'use strict';
// Hook window/document 层面的焦点与可见性检测
function hookGlobalFocus() {
// 拦截 window.onblur
Object.defineProperty(window, 'onblur', {
configurable: true,
enumerable: true,
get() { return null; },
set(v) { console.log('[Hook] 阻止设置 window.onblur:', v); }
});
// 拦截 window.addEventListener('blur', ...)
const _addEventListener = window.addEventListener;
window.addEventListener = function (type, listener, options) {
// 这些事件用于检测离开、切屏、鼠标移出
if (['blur', 'focus', 'visibilitychange', 'mouseleave',
'mouseout', 'pagehide', 'beforeunload', 'unload'].includes(type)) {
console.log('[Hook] 阻止添加事件:', type);
return;
}
return _addEventListener.call(this, type, listener, options);
};
// 拦截 document.onvisibilitychange
Object.defineProperty(document, 'onvisibilitychange', {
configurable: true,
enumerable: true,
get() { return null; },
set(v) { console.log('[Hook] 阻止设置 document.onvisibilitychange:', v); }
});
// 让页面始终认为自己在前台
Object.defineProperty(document, 'hidden', {
configurable: true,
get() { return false; }
});
Object.defineProperty(document, 'visibilityState', {
configurable: true,
get() { return 'visible'; }
});
document.hasFocus = () => true;
}
// 解锁复制/粘贴/右键/选中限制
function unlockPageRestrictions(root = document) {
const eventsToBlock = [
'copy', 'cut', 'paste', 'selectstart', 'contextmenu',
'dragstart', 'mousedown', 'mouseup', 'keydown', 'keyup', 'keypress',
'blur', 'focus', 'visibilitychange',
'mouseleave', 'mouseout', 'pagehide', 'beforeunload', 'unload'
];
// 阻止事件冒泡
eventsToBlock.forEach(event => {
root.addEventListener(event, e => e.stopPropagation(), true);
});
// 遍历所有节点解除绑定与样式
const all = root.querySelectorAll('*');
all.forEach(el => {
el.oncopy = el.oncut = el.onpaste =
el.onselectstart = el.oncontextmenu =
el.ondragstart = el.onmousedown =
el.onmouseup = el.onkeydown = el.onkeypress = null;
el.style.userSelect = 'text';
el.style.webkitUserSelect = 'text';
el.style.msUserSelect = 'text';
el.style.mozUserSelect = 'text';
});
// 解除焦点检测
window.onblur = null;
window.onfocus = null;
document.onvisibilitychange = null;
document.onkeydown = null;
document.oncontextmenu = null;
}
// 遍历 iframe 与 Shadow DOM 深层解锁
function deepUnlock(root = document) {
unlockPageRestrictions(root);
// 处理所有 iframe
root.querySelectorAll('iframe').forEach(iframe => {
try {
const doc = iframe.contentDocument || iframe.contentWindow?.document;
if (doc) {
unlockPageRestrictions(doc);
deepUnlock(doc);
}
} catch (e) {
console.warn('[Tampermonkey] 无法访问 iframe(跨域限制):', e);
}
});
// 递归 Shadow DOM
const traverseShadow = (node) => {
if (!node) return;
if (node.shadowRoot) {
unlockPageRestrictions(node.shadowRoot);
deepUnlock(node.shadowRoot);
}
node.childNodes.forEach(traverseShadow);
};
traverseShadow(root.body || root);
}
// 启动解锁逻辑 + 动态监听 DOM 变化
hookGlobalFocus();
const run = () => {
deepUnlock(document);
};
// 页面加载后运行一次
window.addEventListener('DOMContentLoaded', run);
// 动态监听(防止网站重新注入限制)
const observer = new MutationObserver(() => deepUnlock(document));
observer.observe(document, { childList: true, subtree: true });
})();