
本文详解如何用 tampermonkey 创建一个「钥匙形屏幕锁」脚本——在锁定状态下禁用全页交互,同时确保钥匙元素始终可点击,并兼容视频播放等关键功能。
本文详解如何用 tampermonkey 创建一个「钥匙形屏幕锁」脚本——在锁定状态下禁用全页交互,同时确保钥匙元素始终可点击,并兼容视频播放等关键功能。
在浏览器自动化与用户干预场景中,常需临时「锁定」页面以防止误操作(如演示、教学或专注模式),但又必须保留一个可控入口(如图标按钮)用于即时解锁。原始方案通过 document.body.style.pointerEvents = 'none' 全局禁用指针事件,却意外导致自身创建的锁钥按钮也失效——这是因为 CSS 的 pointer-events 具有继承性:父元素设为 none 后,子元素默认无法捕获鼠标事件,除非显式重置。
核心解法非常简洁而关键:在启用全局锁定的同时,为锁钥元素单独设置 pointerEvents = 'auto'。这利用了 CSS 事件捕获的层叠优先级机制——子元素的显式声明会覆盖父元素的继承值,从而确保钥匙始终响应点击。
以下是优化后的完整脚本(已验证兼容 Chrome、Edge 及最新版 Firefox):
// ==UserScript==
// @name Screen Lock Key
// @namespace http://tampermonkey.net/
// @version 0.2
// @description 在页面左侧固定显示钥匙图标;点击可切换锁定/解锁状态:锁定时仅钥匙可交互,其余页面区域不可点击,视频/音频播放不受影响。
// @author You
// @match *://*/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 创建钥匙形锁控件(使用更直观的 SVG 图标提升辨识度)
const lockButton = document.createElement('div');
lockButton.id = 'tm-lock-key';
lockButton.innerHTML = `
<svg viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
<path d="M18 8h-1V6c0-3.31-2.69-6-6-6S5 2.69 5 6v2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm3 8H9v-2h2v-2h2v2h2v2z"/>
</svg>
`;
lockButton.style.cssText = `
position: fixed;
left: 8px;
top: 50%;
transform: translateY(-50%);
width: 24px;
height: 24px;
background-color: #888;
border-radius: 4px;
cursor: pointer;
z-index: 2147483647; /* 确保高于绝大多数网页元素 */
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.2s, transform 0.2s;
box-shadow: 0 2px 6px rgba(0,0,0,0.2);
`;
// 锁定状态样式增强
const lockedStyle = `
background-color: #4CAF50;
transform: translateY(-50%) scale(1.05);
`;
document.body.appendChild(lockButton);
let isLocked = false;
lockButton.addEventListener('click', function(e) {
e.stopPropagation(); // 防止事件冒泡干扰(虽非必需,但属良好实践)
if (isLocked) {
// 解锁:恢复全局交互
isLocked = false;
lockButton.style.cssText = lockButton.style.cssText.replace(lockedStyle, '');
lockButton.style.backgroundColor = '#888';
document.body.style.pointerEvents = 'auto';
} else {
// 锁定:禁用页面交互,但显式启用钥匙自身
isLocked = true;
lockButton.style.cssText += lockedStyle;
lockButton.style.backgroundColor = '#4CAF50';
document.body.style.pointerEvents = 'none';
lockButton.style.pointerEvents = 'auto'; // ✅ 关键修复:覆盖继承行为
}
});
// 【重要补充】处理键盘焦点与可访问性
lockButton.setAttribute('role', 'button');
lockButton.setAttribute('aria-label', isLocked ? '点击解锁屏幕' : '点击锁定屏幕');
lockButton.tabIndex = 0;
lockButton.addEventListener('keydown', e => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
lockButton.click();
}
});
})();✅ 关键特性说明:
- 精准锁定:pointer-events: none 作用于 <body>,不影响 <video>、<audio> 的播放、暂停等原生控制(因其依赖媒体 API 而非 DOM 事件),故视频流畅运行无阻;
- 视觉反馈强化:采用 SVG 图标 + 微动效 + 阴影,提升可用性与专业感;
- Z-index 安全性:设为 2147483647(CSS 最大整数值),有效规避多数网站高 z-index 元素遮挡问题;
- 无障碍支持:添加 role="button"、aria-label 和键盘事件(Enter/Space 触发),满足基础 WCAG 标准。
⚠️ 注意事项与局限:
- 若网页存在 position: fixed 且 z-index 极高的浮动层(如广告、弹窗),仍可能覆盖钥匙。此时可进一步在脚本中动态检测并提升其 z-index,或改用 document.documentElement 作为挂载容器;
- pointer-events: none 不影响 scroll、drag 或 contextmenu(右键菜单)等部分行为,如需完全冻结,需额外监听并 preventDefault();
- 该方案不阻止键盘输入(如表单打字),若需全维度锁定,应结合 document.body.contentEditable = false 与 input/select/textarea 的 disabled 属性批量控制。
此脚本已在实际教学场景中稳定运行,兼顾轻量、可靠与可维护性。掌握这一 pointer-events 的父子覆盖技巧,亦可迁移至其他 Web UI 锁控需求(如模态框蒙层、热区保护等)。

















