Greasy Fork

Greasy Fork is available in English.

左键限制解除

左键选中

当前为 2025-02-13 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name              左键限制解除
// @description       左键选中
// @version           1
// @match             *://*/*
// @grant             none
// @run-at            document-start
// @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 });
})();