输入框识别按键,自动填充按键组合

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title></title>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
</head>

<body>
    <h2>输入框识别按键,自动填充按键组合</h2>
    <!-- 禁止用户自定义输入,只能按js指定规则生成 -->
    <h3>方案1</h3>
    <input type="text" id="myInput" value="" readonly="readonly" /><br />
    <h3>方案2</h3>
    <input type="text" id="myInput1" value="" readonly="readonly" />
    <button id="add">Add</button>
    <button id="search">search</button>

    <div>
        <ul class="list"></ul>
    </div>

    <div>匹配结果:<span class="result"></span></div>
    <script type="text/javascript">
        // 方案一
        let hotkeyObj = {};
        $("#myInput")
            .on("keydown", function(e) {
                console.log(e);
                const $target = $(e.target);
                const key = e.key === "Control" ? "Ctrl" : e.key;
                const code = e.keyCode;
                if (code !== 8) {
                    hotkeyObj[key] = code;
                    const arr = [];
                    hotkeyObj["Ctrl"] && arr.push("Ctrl");
                    hotkeyObj["Shift"] && arr.push("Shift");
                    hotkeyObj["Alt"] && arr.push("Alt");
                    const specialKeys = ["Ctrl", "Shift", "Alt"];
                    if (!specialKeys.includes(key)) {
                        arr.push(key.toUpperCase());
                    }
                    const hotkey = arr.join("+");
                    $target.val(hotkey);
                    e.preventDefault();
                    return false;
                } else {
                    // Delete键
                    $target.val("");
                }
            })
            .on("keyup", function(e) {
                console.log(e);
                if (!(e.ctrlKey || e.altKey || e.shiftKey)) {
                    // 按键弹起时,如果ctrl / alt / shift键都没有被按住,则重新开始拼接
                    hotkeyObj = {};
                }
            });
        // 方案二:更优
        const isFireFox = navigator.userAgent.indexOf("Firefox/") > 0;
        const isMacOS = navigator.userAgent.indexOf("Mac OS") > 0;
        const keyCodeMap = initMap();

        function init() {
            const hotkeys = getParseHotkeys();
            updateList(hotkeys);
        }
        init();
        $("#myInput1").on("keydown", function(e) {
            const $target = $(e.target);
            const code = e.keyCode;
            e.preventDefault(); // 组织默认行为

            if (code !== 8) {
                const str = parseKey(e);
                $target.val(str);
            } else {
                $target.val("");
            }
        });
        $("#add").on("click", function(e) {
            const hotkey = $("#myInput1").val();
            setHotkeys(hotkey);
            updateList(getParseHotkeys());
            $("#myInput1").val("");
        });
        $("#search").on("click", function(e) {
            // 能将 mac 和 Windows 系统的快捷键相互转化匹配上
            // 1. 需要在拼接按键信息时,区分系统 ---- parseKey
            // 2. 匹配数据时,需要将缓存的数据转义后再进行匹配 ------ fixCtrl
            const hotkey = $("#myInput1").val();
            const hotkeys = getParseHotkeys();
            let result = "";
            hotkeys.forEach((key, i) => {
                if (key === hotkey) {
                    result = hotkey;
                }
            });
            $(".result").html(result || "无");
            $("#myInput1").val("");
        });

        function getHotkeys() {
            let hotkeys = localStorage.getItem("hotkeys");
            return hotkeys ? JSON.parse(hotkeys) : [];
        }
        // 得到根据不同系统转义后的缓存的数据
        // 1. search 匹配数据的时候用
        // 2. updateList 显示数据的时候用
        function getParseHotkeys() {
            const hotkeys = getHotkeys();
            hotkeys.forEach((key, i) => {
                hotkeys[i] = fixCtrl(key);
            });
            return hotkeys;
        }

        function setHotkeys(keyStr) {
            let hotkeys = getHotkeys();
            hotkeys.push(keyStr);
            hotkeys = [...new Set(hotkeys)];
            console.log("hotkeys...", hotkeys);
            localStorage.setItem("hotkeys", JSON.stringify(hotkeys));
            return hotkeys;
        }

        function updateList(hotkeys) {
            const $list = $(".list");
            $list.html("");
            hotkeys.forEach((hotkey) => {
                const li = `<li>${hotkey}</li>`;
                $list.append(li);
            });
        }

        function initMap() {
            const map = {
                8: "Backspace",
                9: "Tab",
                13: "Enter",
                16: "Shift",
                17: isMacOS ? "Control" : "Ctrl",
                18: "Alt",
                27: "Esc",
                32: "Space",
                33: "Page Up",
                34: "Page Down",
                35: "End",
                36: "Home",
                37: "Left",
                38: "Up",
                39: "Right",
                40: "Down",
                45: "Insert",
                46: "Delete",
                91: "Cmd",
                96: "Num0",
                97: "Num1",
                98: "Num2",
                99: "Num3",
                100: "Num4",
                101: "Num5",
                102: "Num6",
                103: "Num7",
                104: "Num8",
                105: "Num9",
                106: "Num*",
                107: "Num+",
                109: "Num-",
                110: "Num.",
                111: "Num/",
                187: "=",
                188: ",",
                190: ".",
                191: "/",
                192: "`",
                219: "[",
                220: "\\",
                221: "]",
                222: "'",
            };
            map[isFireFox ? 59 : 186] = ";";
            map[isFireFox ? 61 : 187] = "=";
            map[isFireFox ? 173 : 189] = "-";
            for (let i = 1; i <= 12; i++) {
                map[111 + i] = "F" + i;
            }
            if (isMacOS) {
                if (isFireFox) {
                    map[224] = "Cmd";
                } else {
                    map[91] = "Cmd";
                    map[93] = "Cmd";
                }
                map[8] = "Delete";
            }
            return map;
        }

        function parseKey(ev) {
            const meta = ev.metaKey,
                ctrl = ev.ctrlKey,
                shift = ev.shiftKey,
                alt = ev.altKey,
                keyCode = ev.keyCode;
            let str = "",
                kStr = keyCodeMap[keyCode];

            if (isMacOS && meta) {
                str += "Cmd+";
            }
            if (ctrl) {
                str += isMacOS ? "Control+" : "Ctrl+";
            }
            if (shift) {
                str += "Shift+";
            }
            if (alt) {
                str += "Alt+";
            }

            if (
                (keyCode >= 48 && keyCode <= 57) ||
                (keyCode >= 65 && keyCode <= 90)
            ) {
                str += String.fromCharCode(keyCode);
            } else if (keyCode >= 96 && keyCode <= 105) {
                // 右侧小键盘上的按键
                str += kStr;
            } else if (
                kStr != "Cmd" &&
                kStr != "Ctrl" &&
                kStr != "Control" &&
                kStr != "Shift" &&
                kStr != "Alt"
            ) {
                // 不是 meta/alt/ctrl/shift
                if (Object.hasOwnProperty.call(keyCodeMap, keyCode)) {
                    str += keyCodeMap[keyCode];
                }
            }

            if (str && /[^+]\+$/.test(str)) {
                str = str.substring(0, str.length - 1);
            }
            return str;
        }
        // 根据不同系统处理  Ctrl/Control/Command,使 MAC 和 Windows 设置的快捷键能够同样
        function fixCtrl(keyStr) {
            if (typeof keyStr === "string") {
                if (isMacOS) {
                    // mac 系统
                    // 将 Windows 系统设置的的 Ctrl => cmd,所以在 Windows 系统设置 Ctrl+S, 在 mac 系统按 Cmd+S 也能使用
                    // mac 系统的 Control 键记录成 Control, Command 键记录成 Cmd
                    keyStr = keyStr.replace(/Ctrl/g, "Cmd");
                } else {
                    // Windows 系统
                    // 将 mac 系统设置的 Control => Ctrl, Cmd => Ctrl, Control+Cmd => Ctrl, 所以在 mac 系统设置 Control+S/Cmd+S, 在 mac 系统按 Ctrl+S 也能使用
                    // Windows 系统的 Ctrl 键记录成 Ctrl
                    keyStr = keyStr.replace(/Control/g, "Ctrl");
                    keyStr = keyStr.replace(/Cmd/g, "Ctrl");
                    keyStr = keyStr.replace(/Control\+Cmd/g, "Ctrl");
                }
            }
            return keyStr;
        }
    </script>
</body>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值