Greasy Fork is available in English.
左键选中
当前为
// ==UserScript==
// @name 左键限制解除
// @description 左键选中
// @version 1
// @match *://*/*
// @run-at document-start
// @grant none
// @namespace http://greasyfork.icu/users/12375
// ==/UserScript==
(() => {
// 数值化事件类型 + 视频白名单
const EV = {
// 基础限制事件
select: 1, // 0b00000001
selectstart: 2, // 0b00000010
copy: 4, // 0b00000100
cut: 8, // 0b00001000
contextmenu: 16, // 0b00010000
// 视频相关事件(白名单)
mousedown: 32, // 0b00100000
mouseup: 64, // 0b01000000
mousemove: 128, // 0b10000000
click: 256 // 0b100000000
};
// 动态元素检测缓存
const videoElements = new WeakMap();
const isVideoControl = (target) => {
while(target) {
if(videoElements.has(target)) return videoElements.get(target);
if(target.tagName === 'VIDEO' ||
target.classList.contains('progress-bar') ||
target.closest('video, [role="video-controls"]')) {
videoElements.set(target, true);
return true;
}
target = target.parentElement;
}
return false;
};
// 原始方法缓存
const { addEventListener: protoAdd } = EventTarget.prototype;
const { preventDefault: protoPrevent } = Event.prototype;
// 智能事件拦截
EventTarget.prototype.addEventListener = function(type, listener, options) {
const eventFlag = EV[type] || 0;
// 基础限制事件 + 非视频相关
if(eventFlag & 0b00011111 && !isVideoControl(this)) {
protoAdd.call(
this,
type,
e => e.stopImmediatePropagation(),
{ capture: true, ...options }
);
}
// 视频事件或非限制事件
else {
protoAdd.call(this, type, listener, options);
}
};
// 动态默认行为控制
Event.prototype.preventDefault = function() {
const eventFlag = EV[this.type] || 0;
const isVideo = isVideoControl(this.target);
// 仅阻止:基础限制事件 + 非视频元素
if((eventFlag & 0b00011111) && !isVideo) {
return; // 不执行默认阻止
} else {
protoPrevent.call(this);
}
};
// 左键解除专用通道
document.addEventListener('click', e => {
if(e.button === 0 && e.target.closest('#unlock-button')) {
// 执行解除逻辑
e.stopPropagation();
handleUnlock();
}
}, { capture: true, passive: true });
})();